• token的使用


    一:什么是token及token的作用?

    1.什么是token?

    Token是首次登录时,由服务器下发,作为客户端进行请求时的一个令牌。当请求后台方法时,用于身份验证

    当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码

    2.Token的作用?

    Token完全由应用程序进行管理,所以它可以避开同源策略
    Token可以避免CSRF(跨站请求访问)攻击 

     简单的说:后端生成token 会有一个签名(基本上后端自己设计)  避免外部攻击!

    Token可以是无状态的,可以在多个服务器之间共享
    使用Token减轻服务器的压力,减少频繁的查询数据库

    3.Token的身份认证过程!

    1.用户通过用户名和密码发送请求

    2.程序进行验证

    3.程序会返回一个字符串(就是token)给客户端

    4.客户端进行储存token,并且用于每一次请求

    5.服务器验证并且返回想要的数据

    现在知道token是干什么的了,那么怎么使用token呢?

     二:JWT介绍

    1.什么是JWT 

    JWT,全称为JSON Web token,是用于对应用程序上的用户进行身份验证的标记。也就是说,使用JWT的应用程序不再需要保存有关其用户的cookie或session数据

    * 在身份验证过程中, 当用户使用其凭据成功登录时,将返回JWT,客户端会将其保存到本地存储中,而后每次请求都会携带

    * JWT本质上就是一个经过加密处理与校验处理的字符串,

    它由三部分组成:头信息.有效载荷.签名
        头信息: 一般由两部分组成,Token类型和散列算法(HMAC、RSASSA、RSASSA-PSS等)

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


        有效载荷: 一般里面可以存储自定义的实体的信息

    payload(载荷)信息存放的是Claims声明信息。载荷其实就是自定义的数据,一般存储用户Id,过期时间等信息。也就是JWT的核心所在,因为这些数据就是使后端知道此token是哪个用户已经登录的凭证。而且这些数据是存在token里面的,由前端携带,所以后端几乎不需要保存任何数据。


        签名: 用于保证消息在传输过程中不会被篡改

    signature(签名)需要使用编码后的header和payload以及一个秘钥,使用header中指定签名算法进行签名。

     2.JWT的流程

     3.项目中使用JWT

    1.依赖

    1. <dependency>
    2. <groupId>io.jsonwebtokengroupId>
    3. <artifactId>jjwtartifactId>
    4. <version>0.9.1version>
    5. dependency>

     2.封装工具类 创建和解析token(调用)

    1. import io.jsonwebtoken.Jwts;
    2. import io.jsonwebtoken.SignatureAlgorithm;
    3. import java.util.Map;
    4. public class JwtUtil {
    5. // 创建token
    6. public static String createToken(Long id,String secret) {
    7. Map map = new HashMap();
    8. map.put("id", id);
    9. return Jwts.builder()
    10. .setClaims(map) //设置响应数据体
    11. .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
    12. .compact();
    13. }
    14. // 解析token
    15. public static Map parseToken(String token,String secret) {
    16. return Jwts.parser().setSigningKey(secret)
    17. .parseClaimsJws(token)
    18. .getBody();
    19. }
    20. }

    最后token 相当于这玩意:

     "token": "eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MTI4fQ.BUsv0fc8qI2Yx02vEDLUR1JSc-FV5Sr8NuqsXIKPiNg"

    生成和解析token工具类

    1. import io.jsonwebtoken.*;
    2. import javax.crypto.SecretKey;
    3. import javax.crypto.spec.SecretKeySpec;
    4. import java.util.*;
    5. public class AppJwtUtil {
    6. // TOKEN的有效期一天(S)
    7. private static final int TOKEN_TIME_OUT = 3_600;
    8. // 加密KEY
    9. private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY";
    10. // 最小刷新间隔(S)
    11. private static final int REFRESH_TIME = 300;
    12. // 生产ID
    13. public static String getToken(Long id){
    14. Map claimMaps = new HashMap<>();
    15. claimMaps.put("id",id);
    16. long currentTime = System.currentTimeMillis();
    17. return Jwts.builder()
    18. .setId(UUID.randomUUID().toString())
    19. .setIssuedAt(new Date(currentTime)) //签发时间
    20. .setSubject("system") //说明
    21. .setIssuer("heima") //签发者信息
    22. .setAudience("app") //接收用户
    23. .compressWith(CompressionCodecs.GZIP) //数据压缩方式
    24. .signWith(SignatureAlgorithm.HS512, generalKey()) //加密方式
    25. .setExpiration(new Date(currentTime + TOKEN_TIME_OUT * 1000)) //过期时间戳
    26. .addClaims(claimMaps) //cla信息
    27. .compact();
    28. }
    29. /**
    30. * 获取token中的claims信息
    31. *
    32. * @param token
    33. * @return
    34. */
    35. private static Jws getJws(String token) {
    36. return Jwts.parser()
    37. .setSigningKey(generalKey())
    38. .parseClaimsJws(token);
    39. }
    40. /**
    41. * 获取payload body信息
    42. *
    43. * @param token
    44. * @return
    45. */
    46. public static Claims getClaimsBody(String token) {
    47. try {
    48. return getJws(token).getBody();
    49. }catch (ExpiredJwtException e){
    50. return null;
    51. }
    52. }
    53. /**
    54. * 获取hearder body信息
    55. *
    56. * @param token
    57. * @return
    58. */
    59. public static JwsHeader getHeaderBody(String token) {
    60. return getJws(token).getHeader();
    61. }
    62. /**
    63. * 是否过期
    64. *
    65. * @param claims
    66. * @return -1:有效,0:有效,1:过期,2:过期
    67. */
    68. public static int verifyToken(Claims claims) {
    69. if(claims==null){
    70. return 1;
    71. }
    72. try {
    73. claims.getExpiration()
    74. .before(new Date());
    75. // 需要自动刷新TOKEN
    76. if((claims.getExpiration().getTime()-System.currentTimeMillis())>REFRESH_TIME*1000){
    77. return -1;
    78. }else {
    79. return 0;
    80. }
    81. } catch (ExpiredJwtException ex) {
    82. return 1;
    83. }catch (Exception e){
    84. return 2;
    85. }
    86. }
    87. /**
    88. * 由字符串生成加密key
    89. *
    90. * @return
    91. */
    92. public static SecretKey generalKey() {
    93. byte[] encodedKey = Base64.getEncoder().encode(TOKEN_ENCRY_KEY.getBytes());
    94. SecretKey key = new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
    95. return key;
    96. }
    97. public static void main(String[] args) {
    98. /* Map map = new HashMap();
    99. map.put("id","11");*/
    100. System.out.println(AppJwtUtil.getToken(1102L));
    101. Jws jws = AppJwtUtil.getJws("eyJhbGciOiJIUzUxMiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAAADWLQQqEMAwA_5KzhURNt_qb1KZYQSi0wi6Lf9942NsMw3zh6AVW2DYmDGl2WabkZgreCaM6VXzhFBfJMcMARTqsxIG9Z888QLui3e3Tup5Pb81013KKmVzJTGo11nf9n8v4nMUaEY73DzTabjmDAAAA.4SuqQ42IGqCgBai6qd4RaVpVxTlZIWC826QA9kLvt9d-yVUw82gU47HDaSfOzgAcloZedYNNpUcd18Ne8vvjQA");
    102. Claims claims = jws.getBody();
    103. System.out.println(claims.get("id"));
    104. }
    105. }

  • 相关阅读:
    四平方和,激光炸弹
    简单的计算器
    【电商运营】直击“废弃购物车”问题核心!
    socket套接字函数
    3D视觉学习路线 + 路线规划
    第10章Swagger自定义实现index.html页
    算法升级之路(二)
    RocketMQ消息发送源码解析
    ubuntu的键盘F1~F12没有反应/出现问题(被系统强制为功能键了)
    计算机毕业设计之java+javaweb的大学生就业帮助系统-就业招聘网站
  • 原文地址:https://blog.csdn.net/weixin_50769390/article/details/127970458