avatar

JWT spring boot JAVA 使用步骤 spring boot2.0

前言

JWT是json web token缩写。它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。

(1)JWT 默认是不加密,但也是可以加密的。生成原始 Token 以后,可以用密钥再加密一次。

(2)JWT 不加密的情况下,不能将秘密数据写入 JWT。

(3)JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询数据库的次数。

(4)JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

(5)JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

(6)为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.util.StringUtils;

public class TokenConfig {
/** token秘钥,请勿泄露,请勿随便修改 backups:JKKLJOoasdlfj */
public static final String SECRET = "JKKLJOoasdlfj";
/** token 过期时间: 10天 */
public static final int calendarField = Calendar.DATE;
public static final int calendarInterval = 10;

/**
* JWT生成Token.<br/>
*
* JWT构成: header, payload, signature
*
* @param user_id
* 登录成功后用户user_id, 参数user_id不可传空
*/
public static String createToken(Long user_id) throws Exception {
Date iatDate = new Date();
// expire time
Calendar nowTime = Calendar.getInstance();
nowTime.add(calendarField, calendarInterval);
Date expiresDate = nowTime.getTime();

// header Map
Map<String, Object> map = new HashMap<>();
map.put("alg", "HS256");
map.put("typ", "JWT");

// build token
// param backups {iss:Service, aud:APP}
String token = JWT.create().withHeader(map) // header
.withClaim("iss", "Service") // payload
.withClaim("aud", "APP").withClaim("user_id", null == user_id ? null : user_id.toString())
.withIssuedAt(iatDate) // sign time
.withExpiresAt(expiresDate) // expire time
.sign(Algorithm.HMAC256(SECRET)); // signature

return token;
}

/**
* 解密Token
*
* @param token
* @return
* @throws Exception
*/
public static Map<String, Claim> verifyToken(String token) {
DecodedJWT jwt = null;
try {
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).build();
jwt = verifier.verify(token);
} catch (Exception e) {
// e.printStackTrace();
// token 校验失败, 抛出Token验证非法异常
}
return jwt.getClaims();
}

/**
* 根据Token获取user_id
*
* @param token
* @return user_id
*/
public static Long getAppUID(String token) {
Map<String, Claim> claims = verifyToken(token);
Claim user_id_claim = claims.get("user_id");
if (null == user_id_claim || StringUtils.isEmpty(user_id_claim.asString())) {
// token 校验失败, 抛出Token验证非法异常
}
return Long.valueOf(user_id_claim.asString());
}
}

概念解析

JWT 的三个部分依次如下。

  • Header(头部)
  • Payload(负载)
  • Signature(签名)

写成一行,就是下面的样子。

https://www.wangbase.com/blogimg/asset/201807/bg2018072303.jpg

文章作者: Derrick
文章链接: http://derricktel.github.io/2019/06/19/JWT-spring-boot-JAVA-%E4%BD%BF%E7%94%A8%E6%AD%A5%E9%AA%A4-spring-boot2-0/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Derrick
打赏
  • 微信
    微信
  • 支付寶
    支付寶