认识JWT
Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。
1. 认证流程
-
首先,前端通过表单提交用户名和密码到后台
-
后台对用户名和密码进行校验,将用户信息(可以是其部分或全部信息)作为
JWT
的Payload(负载),将其与头部分离后分别进行Base64编码拼接后签名,形成JWT(token)。
-
后端将形成的token令牌字符串作为登陆成功后返回的结果保存在前端的localstorage或者sessionstorage中,退出登录时删除token
-
前端在每次请求数据时,将token放入http header中的authorization位置传向后台
-
后台检测token是否存在,存在又是否合法,是否过期。
-
验证通过后使用用户信息中返回的其他信息进行操作,返回数据
2.JWT结构
-
令牌组成(字符串)
- 标头(Header)
- 有效载荷(Payload)
- 签名(Signature)
通常为以下形式:xxxxx.yyyyy.zzzzz ==> Header.Payload.Signature
-
Header
标头通常又两部分组成:令牌的类型(即JWT)和所使用的签名算法,如HMAC SHA256 或者RSA。他会使用Base64编码组成的 JWT 结构的第一部分。
base64enc({
'alg':"HS256",
"type":"JWT"
})
-
Payload
令牌的第二部分是有效负载,其中包含声明。声明时有关联实体(通常是用户)和其他数据的声明。同样的,它会使用Base64编码组成 JWT 结构的第二部分。
base64enc({
'userId':"123456", //用户信息,不要存敏感信息
"nickname":"Jack",
"....":"......",
"expirTime":142654111 //过期时间
})
-
Signature
Signature需要使用编码后的header和payload以及我们提供的一个秘钥,然后使用header中指定的加密算法(HS256)进行签名。签名的作用是保证 JWT 没有被修改过
HMACSHA256(base64enc(header)+"."+base64enc(payload),secretKey)
3.使用
Map<String, Object> map = new HashMap<>();
Calendar instance = Calendar.getInstance();
instance.add(Calendar.SECOND, 20);
//生成token令牌
String token = JWT.create()
.withHeader(map) //header,可以不写,默认的
.withClaim("userId", "123456") //携带信息
.withClaim("nickname", "Jack")
.withExpiresAt(instance.getTime()) //指定过期时间
.sign(Algorithm.HMAC256(secreteKey)); //签名
//验证token令牌
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secreteKey)).build();
DecodedJWT verify = jwtVerifier.verify(token);
System.out.println(verify.getClaim("userId").asString());
System.out.println(verify.getClaim("nickname").asString());
封装
package com.xieqing.jwt.util;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
public class JWTUtils {
private static final String secreteKey = "secrete-xq4077";
public static String getToken(Map<String, String> data) {
Calendar instance = Calendar.getInstance();
instance.add(Calendar.DATE, 7); //七天过期
Map<String, Object> map = new HashMap<>();
JWTCreator.Builder builder = JWT.create();
data.forEach((k, v) -> {
builder.withClaim(k, v);
});
String token = builder.withExpiresAt(instance.getTime()).sign(Algorithm.HMAC256(secreteKey));
return token;
}
/**
* 验证token的合法性,如果算法不正确,签名不匹配,时间过期,则会抛异常,若可以使用,则返回decoderJWT,可获取信息
*
* @param token
*/
public static DecodedJWT verifyToken(String token) {
return JWT.require(Algorithm.HMAC256(secreteKey)).build().verify(token);
}
}
标题: | JWT令牌生成 |
---|---|
链接: | https://www.fightingok.cn/detail/18 |
更新: | 2022-09-18 22:32:02 |
版权: | 本文采用 CC BY-NC-SA 3.0 CN 协议进行许可 |