JWT

JSON Web Token (JWT) 是一种开放标准 (RFC 7519),它定义了一种紧凑且独立的方式,用于将信息作为 JSON 对象在各方之间安全地传输。
此信息可以验证和信任,因为它是数字签名的。可以使用密钥(使用 HMAC 算法)或使用 RSA 或 ECDSA 的公钥/私钥对 JWT 进行签名。


JSON Web Token组成:

Header(头部)——base64Url编码的Json字符串
Payload(载荷)——base64url编码的Json字符串
Signature(签名)——使用指定算法,通过Header和Playload加盐计算的字符串

Header部分

{
	"alg","HS256"// 指定算法
	"typ","JWT"// 指定类型
}

查看jwt各版本支持的算法:https://jwt.io/libraries

Payload(负载)部分
其中包含三种类型claims(声明)

  • Registered(已注册的声明)
JWT 规定了7个官方字段:
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
定义私有字段:
{
  "sub": "1234567890",
  "name": "John",
  "admin": true
}
  • Public(公开声明):
    这些可以由使用JWT的人随意定义。
    但为避免冲突,应在IANA JSON Web Token Registry中定义它们,
    或者将其定义为包含防冲突命名空间的URI。

  • private (私人声明):
    这些声明是为了在同意使用它们的各方之间共享信息而创建的,
    并且既不是注册声明也不是公开声明。

Signature(签名)部分
是对前两部分的签名,防止数据篡改。

首先,需要指定一个密钥(secret)(字符串常量)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
HMACSHA256(
base64UrlEncode(header) + “.” +
base64UrlEncode(payload),
secret)
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。

JWT 的使用方式

客户端收到服务器返回的 JWT,你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。
Authorization: Bearer jwtToken
另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。

JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效
解决方案:登录成功时将jwtToken存入redis中,退出时删除redis中的数据,如果jwtToken还未过期,检查redis中是否有该token,有就放行,没有就重新登录。

代码实现

依赖

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-api</artifactId>
    <version>0.11.2</version>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-impl</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>
<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt-jackson</artifactId>
    <version>0.11.2</version>
    <scope>runtime</scope>
</dependency>

生成 jwt

String key = "xxxxxxxxxxxxxxxxxxxxxxxxx";
// 安全密钥
SecretKey secretKey = Keys.hmacShaKeyFor(key.getBytes(StandardCharsets.UTF_8));
Date date =new Date();
String jwt = Jwts.builder()
        // 安全密钥和加密方式
        .signWith(secretKey,SignatureAlgorithm.HS256)
        // 过期时间
        .setExpiration(DateUtils.addMinutes(date,10))
        // 签发时间
        .setIssuedAt(date)
        // id
        .setId(uuid)
        // 负载数据
        .addClaims(new HashMap<String,Object>())
        .compact();

解析 jwt

Jws<Claims> claimsJws = Jwts.parserBuilder()
        .setSigningKey(secretKey)
        .build()
        .parseClaimsJws(jwt);
// 读取数据
Claims body = claimsJws.getBody();
Integer userId = body.get("userId", Integer.class);
Object userId1 = body.get("userId");
String id = body.getId();
Date issuedAt = body.getIssuedAt();
Date expiration = body.getExpiration();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值