什么是JWT?

JWT是一种用于进行用户鉴权的技术。通过这个技术确定当前访问者的身份
代替了Session和Token的方式存储用户身份信息

实现方式

jwt通过了三段数据来记录所需要的信息
Header.Payload.Signature

Header

第一部分是头部分,它是一个描述JWT元数据的Json对象,通常如下所示。

  1. {
  2. "alg": "HS256",
  3. "typ": "JWT"
  4. }

alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256),typ属性表示令牌的类型,JWT令牌统一写为JWT。
最后,使用Base64 URL算法将上述JSON对象转换为字符串保存。

Payload

第二部分,也是一个json对象,除了包含需要传递的数据,还有七个字段可以选择
iss:发行人
exp:到期时间
sub:主题
aud:用户
nbf:在此之前不可用
iat:发布时间
jti:JWT ID用于标识该JWT

  1. {
  2. //默认字段
  3. "sub":"主题123",
  4. //自定义字段
  5. "name":"java技术爱好者",
  6. "isAdmin":"true",
  7. "loginTime":"2021-12-05 12:00:03"
  8. }

需要注意的是,默认情况下JWT是未加密的,任何人都可以解读其内容,因此如果一些敏感信息不要存放在此,以防信息泄露。
JSON对象也使用Base64 URL算法转换为字符串保存

Signature

第三部分是签名。是这样生成的,首先需要指定一个secret,该secret仅仅保存在服务器中,保证不能让其他用户知道。然后使用Header指定的算法对Header和Payload进行计算,然后就得出一个签名哈希。也就是Signature
那么Application Server如何进行验证呢?可以利用JWT前两段,用同一套哈希算法和同一个secret计算一个签名值,然后把计算出来的签名值和收到的JWT第三段比较,如果相同则认证通过。

JWT使用方法

  1. 导入maven依赖 ```java io.jsonwebtoken jjwt 0.9.1
  1. 2. 创建工具类,用于创建jwt字符串和解析jwt
  2. ```java
  3. @Component
  4. public class JwtUtil {
  5. @Value("${jwt.secretKey}")
  6. private String secretKey;
  7. public String createJWT(String id, String subject, long ttlMillis, Map<String, Object> map) throws Exception {
  8. JwtBuilder builder = Jwts.builder()
  9. .setSubject(null) // 发行者
  10. .setId(id)
  11. .setSubject(subject)
  12. .setIssuedAt(new Date()) // 发行时间
  13. .signWith(SignatureAlgorithm.HS256, secretKey) // 签名类型 与 密钥
  14. .compressWith(CompressionCodecs.DEFLATE);// 对载荷进行压缩
  15. if (!CollectionUtils.isEmpty(map)) {
  16. builder.setClaims(map);
  17. }
  18. if (ttlMillis > 0) {
  19. builder.setExpiration(new Date(System.currentTimeMillis() + ttlMillis));
  20. }
  21. return builder.compact();
  22. }
  23. public Claims parseJWT(String jwtString) {
  24. return Jwts.parser().setSigningKey(secretKey)
  25. .parseClaimsJws(jwtString)
  26. .getBody();
  27. }
  28. }
  1. 接着在application.yml配置文件配置jwt.secretKey

    ## 用户生成jwt字符串的secretKey
    jwt:
    secretKey: ak47
    
  2. 接着创建一个响应体 ```java public class BaseResponse {

    private String code;

    private String msg;

    public static BaseResponse success() {

     return new BaseResponse("0", "成功");
    

    }

    public static BaseResponse fail() {

     return new BaseResponse("1", "失败");
    

    } //构造器、getter、setter方法 }

public class JwtResponse extends BaseResponse {

private String jwtData;

public static JwtResponse success(String jwtData) {
    BaseResponse success = BaseResponse.success();
    return new JwtResponse(success.getCode(), success.getMsg(), jwtData);
}

public static JwtResponse fail(String jwtData) {
    BaseResponse fail = BaseResponse.fail();
    return new JwtResponse(fail.getCode(), fail.getMsg(), jwtData);
}
//构造器、getter、setter方法

} ```

  1. 通过三层架构调用相应的方法匹配用户的身份(从服务器里)