jwt由来
- 由于http是无状态的传输协议,所以每一次请求都要带上身份信息。实现方式是创建一个叫会话(session)的概念,服务器端session存储用户的信息,客户端通过cookie存放sessionid,每次请求都带上cookie,以验证sessionid
- 因为cookie容易被恶意篡改、sessionid存储的信息太单一、session管理复杂(多服务器导致session需要统一管理)等问题,jwt出现了
- jwt在服务器端生成,再传给前端。后端可以解码每次请求携带的jwt,不需要单独存储也可以获取当前的用户信息,并且可以防止被人篡改
jwt简介
JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用JWT在用户和服务器之间传递安全可靠的信息。
jwt结构
token = {header}.{payload}.{signature}
- header 存放jwt最基本的信息,包括加密算法的类型等,然后进行base64加密
- payload 存放有效信息(JSON),如:
然后进行base64加密iss: jwt签发者 sub: jwt所面向的用户 aud: 接收jwt的一方 exp: jwt的过期时间,这个过期时间必须要大于签发时间 nbf: 定义在什么时间之前,该jwt都是不可用的. iat: jwt的签发时间 jti: jwt的唯一身份标识,主要用来作为一次性token。 自定义的信息,如useid等 上述信息不一定要都有
- signature 由三部分组成:加密后的header + 加密后的payload + secret
springboot整合jwt
<dependency>
<!-- jwt依赖 -->
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.10.3</version>
</dependency>
// 根据uid生成并返回一个token
@GetMapping("/get/token/{uid}")
public String setToken(@PathVariable("uid") String uid) {
HashMap<String, Object> map = new HashMap<>();
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DATE, 7);
String token = JWT.create()
.withHeader(map) // header map为空则为默认值
.withClaim("uid", uid) // payload
.withClaim("usage", "just a demo for jwt")
.withExpiresAt(instance.getTime()) // 设置过期时间
.sign(Algorithm.HMAC256("secret12138")); //secret
return token;
}
// 根据token验证并获取uid
@GetMapping("/check/token/{token}")
public boolean checkToken(@PathVariable("token") String token) {
try {
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();
DecodedJWT verify = jwtVerifier.verify(token);
String uid = verify.getClaim("uid").asString();
if (uid==null || "".equals(uid)) {
return false;
}else {
return true;
}
}catch (Exception e) {
e.printStackTrace();
return false;
}
}