JWT初步了解

JWT


1、Session 存放服务器端— Session ID

2、Token + Redis

Session 缺点集群无法共享 — redis 中

Token 类似于 Session ID

Token 依赖于 Redis 真实 token 存放 value 值

使用 Token 缺点:每次都需要根据 token查询真实的内容,对服务器端压力就非常大。

jwt 先学习 json、token (加密算法 对称非对称加密算法)

Jwt 底层组成部分:

1、Header(头) 作用:记录令牌类型。签名算法等
2、Payload(有效载荷) 作用:携带一些用户信息 
3、Signature(签名) 作用:防止 Token 被篡改。确保安全性

1、头部

header

  • 声明类型,这里是jwt
  • 声明加密的算法 通常直接使用 HMAC SHA256
{
  'typ': 'JWT',
  'alg': 'HS256'
}

然后将头部进行base64加密(该加密是可以对称解密的),构成了第一部分.

在header 描述 jwt 的 Payload 加密方式

2、Payload 装载的数据

  • 标准中注册的声明
  • 公共的声明
  • 私有的声明

标准中注册的声明 (建议但不强制使用) :

  • iss:jwt签发者
  • sub:jwt所面向的用户
  • aud:接收jwt的一方
  • exp:jwt的过期时间,这个过期时间必须要大于签发时间
  • nbf:定义在什么时间之前,该jwt都是不可用的.
  • iat:jwt的签发时间
  • jti: jwt的唯一身份标识,主要用来作为一次性token,从而回避重放攻击。

公共的声明
公共的声明可以添加任何的信息,一般添加用户的相关信息或其他业务需要的必要信息.但不建议添加敏感信息,因为该部分在客户端可解密.

私有的声明
私有声明是提供者和消费者所共同定义的声明,一般不建议存放敏感信息,因为base64是对称解密的,意味着该部分信息可以归类为明文信息。

Payload 就是 jwt 存放的数据内容

{
"userId":"1234"
"userName":"liujianyu"
"过期时间。。。。"
}
注意在 Pyload 中不能够存放敏感数据-(手机号、密码。。。。)

然后将其进行base64加密,得到Jwt的第二部分。

Token 对应存放在 Redis 或者数据库中的数据

3、验证签名

jwt的第三部分是一个签证信息,这个签证信息由三部分组成:

  • header (base64后的)
  • payload (base64后的)
  • secret

这个部分需要 base64 加密后的 header 和 base64 加密后的 payload 使用.连接组成的字符串,然后通过header中声明的加密方式进行加盐secret组合加密,然后就构成了jwt的第三部分。

Jwt与token最大的区别:

  • token依赖于Redis 查询数据信息,token存放value数据比较安全的。
  • Jwt 不需要依赖于服务器端,将数据信息内容直接存放在客户端(浏览器)

在这里插入图片描述

Jwt payload 的数据是无法被篡改的

JWT优缺点

优点:

1、无需在服务器存放用户的数据,减轻服务器端压力

2、轻量级、json风格比较简单

3、跨语言

缺点:

jwt 一旦生成后期无法修改

1、无法更新 jwt 有效期

2、无法销毁一个 jwt

导入依赖

  <!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.1</version>
        </dependency>

<!-- 这三个依赖是解决jdk版本过高问题 -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-core -->
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-core</artifactId>
            <version>3.0.0</version>
        </dependency>

创建 Token

private static String signature = "admin";

private static long time = 1000*60*60*24; //单位毫秒,一天

JwtBuilder jwtBuilder = Jwts.builder();
String jwtToken = jwtBuilder
    .setHeaderParam("typ", "JWT")
    .setHeaderParam("alg", "HS256")
    //Payload
    .claim("role", "admin")
    .claim("userName", "liujian")
    .setSubject("admin-test")//设置主题
    .setExpiration(new Date(System.currentTimeMillis() + time))
    .setId(UUID.randomUUID().toString())
    //signature
    .signWith(SignatureAlgorithm.HS256, signature)
    .compact();//拼接

解析 token

String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYWRtaW4iLCJ1c2VyTmFtZSI6ImxpdWppYW4iLCJzdWIiOiJhZG1pbi10ZXN0IiwiZXhwIjoxNjI0MTYzMDIxLCJqdGkiOiJlNWNiZjAwNy01MDYzLTQ3YzktOTk1OC03NTA0YTAzYTE3NmQifQ.lzi0a5vMRUKFT4AbBrZuBV44qFVQdye3WacqKXo6CW8";

JwtParser parser = Jwts.parser();
Jws<Claims> claimsJws = parser.setSigningKey(signature).parseClaimsJws(token);

Claims claims = claimsJws.getBody();

System.out.println(claims.get("userName"));
System.out.println(claims.get("role"));
System.out.println(claims.getId());
System.out.println(claims.getSubject());
System.out.println(claims.getExpiration());
System.out.println(claims);

输出结果

liujian
admin
e5cbf007-5063-47c9-9958-7504a03a176d
admin-test
Sun Jun 20 12:23:41 CST 2021
{
    
    role=admin, userName=liujian, sub=admin-test, exp=1624163021, jti=e5cbf007-5063-47c9-9958-7504a03a176d}

おすすめ

転載: blog.csdn.net/qq_51998352/article/details/118068415