目前 Token 为 RSA JWT 签发,其他前端接口应用可使用如下方法对 SessionToken 进行验证,并调用用户服务得到基本用户信息。

使用 JJWT 验证

基本资料要求

签发证书的公钥信息

例如:

  1. String publicKeyStr = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmt7JOPddMs8Cw/AS3/gzu6k3DjN8kobMz+tE1vVlph8X+z+voq5LDY/tQJWaN2Y9PBbOea3IOwMp4dgruaSZ40pKNrJ2bPr86z0drnn0ztgQSDXYQjX+iyEQmGcjAOdH6XFi+kn/J3OCXYSRV8W8ipeHMolmwzgus/O2W609djb6YGg1Ci8ppzgWtzmtIGz05VKEVZp2ST/ucwey5VT35n1K1MGofifuAhwALhTjgfBYxf2gHoQhttV8uofV3HI7gQbDooIW8/5+H/jGcZmolZ5CudigjeS5QyDMUKASv8D++IWepucJ4XVhqxttgUfh8vSuDJ67ba9zH84CCtzI5wIDAQAB";
  2. KeyFactory kf = KeyFactory.getInstance("RSA");
  3. X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(SecurityUtils.decodeBase64(publicKey));
  4. PublicKey publicKey = kf.generatePublic(x509EncodedKeySpec);

签发时的相关信息

  1. public class TokenConstants {
  2. public final static String ISSUER = "NXCloud-GM";
  3. public final static String SUBJECT_SESSION = "BFF-C-Session";
  4. public final static String SUBJECT_USER = "BFF-C-User";
  5. public final static long EXPIRATION_SESSION = 600000;
  6. public final static long EXPIRATION_USER = 604800000;
  7. public final static String CLAIM_USER_KEY = "userKey";
  8. }

添加 JJWT 依赖

<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-api</artifactId>
</dependency>
<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-impl</artifactId>
</dependency>
<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt-jackson</artifactId>
</dependency>

验证 Token

// 验证 SessionToken
String authorization = request.getHeader("Authorization");
if (StringUtils.isEmpty(authorization)) {
    throw new SessionTokenNotFoundException("未包含 Session 认证信息");
}
String jwtToken = StringUtils.substringAfter(authorization, "Bearer ");
if (StringUtils.isEmpty(jwtToken)) {
    throw new SessionTokenNotFoundException("未找到 SessionToken");
}

Claims claimsBody;
try {
    claimsBody = Jwts.parserBuilder()
        .setSigningKey(runtimeInfo.getPublicKey())
        .requireIssuer(TokenConstants.ISSUER)
        .requireSubject(TokenConstants.SUBJECT_SESSION)
        .build()
        .parseClaimsJws(jwtToken).getBody();
} catch (Exception e) {
    throw new SessionTokenInvalidException("验证 SessionToken 出错", e);
}

String userKey = claimsBody.get(TokenConstants.CLAIM_USER_KEY, String.class);
if (StringUtils.isEmpty(userKey)) {
    throw new SessionTokenInvalidException("未找到用户信息");
}

// TODO 根据 userKey 调用用户服务获取用户信息