1.用户登录时,将客户端发来的登录信息保存到服务端的session作用域中
2.然后这份信息在响应时传递给浏览器,并保存为cookie(含有JSESSIONID)
3下次识别根据JESSIONID来查找对应的session
(1).引入依赖
com.auth0
java-jwt
3.4.0
(2).生成jwt的token
@Test
void jwtCreate() {
//设置token的过期时间
Date date = new Date(System.currentTimeMillis() + 100 * 1000);
//设置token的Header,一般默认,可以不用设置 (默认形式:jwt,默认算法:HMAC256)
Map map = new HashMap<>();
//获得token
String token = JWT.create()
.withHeader(map) //设置Header
.withClaim("userId", 13) //设置Payload 非敏感值
.withClaim("userName", "admin")
.withExpiresAt(date) //设置过期时间
.sign(Algorithm.HMAC256("@312ewe")); //通过Header规定的算法,传入自定义的密钥
System.out.println(token);
}
(3)验证token
@Test
void jwtVerify() {
//根据相同的密钥和算法创建一个jwt验证器
JWTVerifier verifier = JWT.require(Algorithm.HMAC256("@312ewe")).build();
//用验证器进行验证,得到已解码的jwt
DecodedJWT decodedJwt = verifier.verify("自己构造的token(令牌)");
//通过已解码的jwt取出Payload
System.out.println(decodedJwt.getClaim("userId").asInt());
System.out.println(decodedJwt.getClaim("userName").asString());
}
(4)构造JwtUtils简化使用
public class JwtUtils {
//设置默认时间
public final static long EXPIRE_TIME = 30 * 60 * 1000;
//设置密钥
public final static String SECRET= "@qwq>< map) {
//获得jwt构造器
JWTCreator.Builder builder = JWT.create();
//builder.withHeader() 一般默认,不需要修改
//设置Payload
map.forEach((k,v) -> {
builder.withClaim(k,v);
});
//设置过期时间
builder.withExpiresAt(new Date(System.currentTimeMillis() +EXPIRE_TIME));
//设置密钥,获得token(令牌)
String token =builder.sign(Algorithm.HMAC256(SECRET));
return token;
}
/**
* 验证token是否合法
* @param token 前端传来的令牌
* @return 已解码的jwt
*/
public static DecodedJWT verify(String token) {
//获得jwt注册器
JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SIGN)).build();
return verifier.verify(token);
}
}
(5)设置拦截器
public class JwtInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//一般token放在请求头中
String token = request.getHeader("token");
HashMap map = new HashMap<>();
try{
//使用JwtUtils验证token的合法性
DecodedJWT decodedJWT = JwtUtils.verify(token);
//认证成功,进行放行
return true;
}catch (SignatureVerificationException e){
map.put("status", false);
map.put("msg", "签名验证异常");
}catch (AlgorithmMismatchException e){
map.put("status", false);
map.put("msg", "算法不匹配异常");
}catch (TokenExpiredException e){
map.put("status", false);
map.put("msg", "令牌过期异常");
}catch (InvalidClaimException e){
map.put("status", false);
map.put("msg", "失效的payload异常");
}catch (Exception e) {
map.put("status", false);
map.put("msg", "其他异常");
}
//map数据转换成json
String json = new ObjectMapper().writeValueAsString(map);
response.setContentType("application/json;charset=UTF-8");
response.getWriter().println(json);
return false;
}
}
(6)加入拦截器
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new JwtInterceptor())
.addPathPatterns("/**") //一般拦截所有请求
.excludePathPatterns("/user/**"); //不拦截与用户有关的注册请求
}
}