• JWT的基础介绍


    前言

    JWT主要是用于用户登录鉴权,传统的方法就是session认证。

    http是无状态的协议,当有用户向系统使用账户名称和密码进行用户认证之后,下一次请求还要再一次用户认证才行。因为我们不能通过http协议知道是哪个用户发出的请求,所以如果要知道是哪个用户发出的请求,那就需要在服务器保存一份用户信息(保存至session),然后在认证成功后返回cookie值传递给浏览器,那么用户在下一次请求时就可以带上cookie值,服务器就可以识别是哪个用户发送的请求,是否已认证,是否登录过期等等。

    session认证的缺点其实很明显,由于session是保存在服务器里,所以如果分布式部署应用的话,会出现session不能共享的问题,很难扩展。

    JWT的介绍

    JWT:Json Web Token 它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

     流程:

    • 用户使用账号、密码登录应用,登录的请求发送到Authentication Server。
    • Authentication Server进行用户验证,然后创建JWT字符串返回给客户端。
    • 客户端请求接口时,在请求头带上JWT。
    • Application Server验证JWT合法性,如果合法则继续调用应用接口返回结果

    用户信息是保存在客户端,关键在于生成JWT和解析JWT。

    JWT的数据结构

    JWT一般是这样的字符串,分为三个部分,以"."隔开。

    xxxxx.yyyyy.zzzzz

    Header:第一部分是头部分,描述JWT元数据的Json对象

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

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

    Payload:第二部分是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. }

    JSON对象也使用Base64 URL算法转换为字符串保存。

    Signature:第三部分是签名。是这样生成的,首先需要指定一个secret,该secret仅仅保存在服务器中,保证不能让其他用户知道。然后使用Header指定的算法对Header和Payload进行计算,然后就得出一个签名哈希。

    JWT的优点:

    • json格式的通用性,所以JWT可以跨语言支持,比如Java、JavaScript、PHP、Node等等。
    • 可以利用Payload存储一些非敏感的信息。
    • 便于传输,JWT结构简单,字节占用小。
    • 不需要在服务端保存会话信息,易于应用的扩展。

    使用JWT 

    导入依赖

    1. <dependency>
    2. <groupId>io.jsonwebtoken</groupId>
    3. <artifactId>jjwt</artifactId>
    4. <version>0.9.1</version>
    5. </dependency>

    创建工具类,用于创建jwt字符串和解析jwt

    1. import io.jsonwebtoken.Claims;
    2. import io.jsonwebtoken.JwtBuilder;
    3. import io.jsonwebtoken.Jwts;
    4. import java.util.Date;
    5. /**
    6. *
    7. * @description JWT:令牌token生成
    8. */
    9. public class TokenUtil {
    10. // token有效期
    11. private static final long EXPIRATION = 86400L;//1day = 86400L
    12. /**
    13. *
    14. * @description 创建token工具方法
    15. */
    16. public static String createToken(User user) {
    17. JwtBuilder builder = Jwts.builder();
    18. builder.setAudience(user.getUserCode()) // 这个user.getUserCode()是我后续需要的参数
    19. .setIssuer("xxx")
    20. .claim("userId", user.getId()) // userId 是我自己后续需要的参数,这个根据自己的需求进行设置
    21. .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION * 1000));
    22. String accessToken = builder.compact();
    23. return accessToken;
    24. }
    25. /**
    26. *
    27. * @description 验证token返回用户code
    28. */
    29. public static String validateToken(String token) {
    30. Claims claims = Jwts.parserBuilder().build().parseClaimsJwt(token).getBody();
    31. String userCode = claims.getAudience();
    32. return userCode;
    33. }
    34. /**
    35. *
    36. * @description 验证token返回用户ID
    37. */
    38. public static String getUserIdFromToken(String token) {
    39. Claims claims = Jwts.parserBuilder().build().parseClaimsJwt(token).getBody();
    40. String userId = claims.get("userId", String.class);
    41. return userId;
    42. }
    43. }

    有些微修改,我这里没有使用到第三部分。
    链接:https://www.zhihu.com/question/485758060/answer/2257869896

  • 相关阅读:
    [卷积神经网络]FasterNet论文解析
    【成为红帽工程师】第一天 例行性工作与chrony服务器
    34汽车租聘系统Javaweb ssm
    git问题: git@10.18.*.*: Permission denied (publickey,password)
    零基础也能制作小说推文视频,输入文案就能制作推文短视频
    一切皆可盲盒:孙宇晨传递给商业太空旅游的机会
    云计算模式的区域LIS系统源码,基于ASP.NET+JQuery、EasyUI+MVC技术架构开发
    火山引擎DataTester智能发布:助力产品降低功能迭代风险
    开发JSP应用的基础知识
    Java面试题07-HashMap的扩容原理
  • 原文地址:https://blog.csdn.net/qq_45443879/article/details/125594618