剖析JWT,及其的使用案例

嚴華  金牌会员 | 2023-7-20 04:29:13 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 915|帖子 915|积分 2745

什么是JWT


  • JWT 是一个开放标准,它定义了一种用于简洁,自包含的用于通信双方之间以 JSON 对象的形式安全传递信息的方法。 可以使用 HMAC 算法或者是 RSA 的公钥密钥对进行签名
  • 简单来说: 就是通过一定规范来生成token,然后可以通过解密算法逆向解密token,这样就可以获取用户信息
  • 优点

    • 生产的token可以包含基本信息,比如id、用户昵称、头像等信息,避免再次查库
    • 存储在客户端,不占用服务端的内存资源

  • 缺点

    • token是经过base64编码,所以可以解码,因此token加密前的对象不应该包含敏感信息,如用户权限,密码等
    • 如果没有服务端存储,则不能做登录失效处理,除非服务端改秘钥

JWT格式组成 头部、负载、签名


  • header+payload+signature

    • 头部:主要是描述签名算法
    • 负载:主要描述是加密对象的信息,如用户的id等,也可以加些规范里面的东西,如iss签发者,exp 过期时间,sub 面向的用户
    • 签名:主要是把前面两部分进行加密,防止别人拿到token进行base解密后篡改token

关于jwt客户端存储


  • 可以存储在cookie,localstorage和sessionStorage里面
代码实现


  • 依赖引入
    1. <dependency>
    2.     <groupId>io.jsonwebtoken</groupId>
    3.     <artifactId>jjwt</artifactId>
    4.     <version>0.7.0</version>
    5. </dependency>
    复制代码
  • JWTUtil类,封装了生产token方法和校验token方法
    1. @Slf4j
    2. public class JWTUtil {
    3.     /**
    4.      * 主题
    5.      */
    6.     private static final String SUBJECT = "xtw";
    7.     /**
    8.      * 加密秘钥
    9.      */
    10.     private static final String SECRET = "xtw.com";
    11.     /**
    12.      * 令牌前缀
    13.      */
    14.     private static final String TOKEN_PREFIX = "xtwcloud-link";
    15.     /**
    16.      * 过期时间 7天
    17.      */
    18.     private static final long EXPIRED = 1000*60*60*24*7;
    19.     /**
    20.      * 生成token
    21.      * @param loginUser
    22.      * @return
    23.      */
    24.     public static String geneJsonWebToken(LoginUser loginUser){
    25.         if(loginUser == null){
    26.             throw new NullPointerException("对象为空");
    27.         }
    28.         String token = Jwts.builder().setSubject(SUBJECT)
    29.                 // 配置payload
    30.                 .claim("head_img",loginUser.getHeadImg())
    31.                 .claim("account_no",loginUser.getAccountNo())
    32.                 .claim("username",loginUser.getUserName())
    33.                 .claim("mail",loginUser.getMail())
    34.                 .claim("phone",loginUser.getPhone())
    35.                 .claim("auth",loginUser.getAuth())
    36.                 .setIssuedAt(new Date())
    37.                 .setExpiration(new Date(CommonUtil.getCurrentTimestamp()+EXPIRED))
    38.                 .signWith(SignatureAlgorithm.HS256,SECRET).compact();
    39.         token = TOKEN_PREFIX + token;
    40.         return token;
    41.     }
    42.     /**
    43.      * 校验token
    44.      * @param token
    45.      * @return
    46.      */
    47.     public static Claims checkJWT(String token){
    48.         try {
    49.             final Claims claims = Jwts.parser().setSigningKey(SECRET)
    50.                     .parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
    51.                     .getBody();
    52.             return claims;
    53.         }catch (Exception e){
    54.             log.info("jwt 校验失败");
    55.             return null;
    56.         }
    57.     }
    58. }
    复制代码
  • 案例

    • 用户初次登录或者token过期,登录成功返回JWT令牌
      1. public JsonData login(AccountLoginRequest loginRequest) {
      2.     // 校验用户账号和密码,等...  TODO
      3.    
      4.     // 对象变迁 loginRequest -> DO -> DTO(loginUser)
      5.     // loginRequest:前端输入
      6.     // DO:根据loginRequest从数据库中提取
      7.           // DTO(loginUser):剔除了DO中的敏感字段,用于生成token
      8.    
      9.     // 密码正确 生成JWT_token
      10.     String token = JWTUtil.geneJsonWebToken(loginUser);
      11.     return JsonData.buildSuccess(token);
      12. }
      复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

嚴華

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表