本文共 4798 字,大约阅读时间需要 15 分钟。
jwt(JSON Web Token)
JSON Web Token (JWT) is an open standard () that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
Jwt简介
-
传统认证通过session,但是前后端分离和分布式项目无法使用,
-
jwt向认证成功的用户返回一个token,以后用户每次请求都携带该token来实现认证
-
请求认证的token存放在客户端
localStorage
中,请求时数据携带在header中,退出登录在loacalStorage中删除该token即可
JWT结构
组成
jwt令牌由三部分组成
- 头部(Header)
- 有效荷载(payload)
- 签名(signature)
因此,JWT通常是xxxx.yyy.zzz
的形式
头部(Header)
明文示例
{ "alg":"HS256", "typ":"JWT"}
alg
:加密算法
typ
:类型
header部分会使用base64
编码,注意,base64并不是加密的过程,可以解码
Payload
{ "sub":"123465", "name":"zhansan", "admin":true}
数据负载部分也会使用base64进行编码,payLoad不要存放用户敏感信息
签名(signature)
签名使用编码后的header和payload,以及一个密钥,然后使用header中指定的签名算法进行签名,签名的作用是保证JWT没有被篡改过
使用
pom依赖
com.auth0 java-jwt 3.4.0
生成token
//加密口令String SECRET = "!Q$#&^&SCMd12";Algorithm algorithm = Algorithm.HMAC256(SECRET);//设施过期时间为10minCalendar expireTime =Calendar.getInstance();expireTime.add(Calendar.MINUTE,10);Mapmap = new HashMap<>();map.put("alg","HS256");map.put("typ","JWT");String tokenStr = JWT.create() //header可以不用设置,一般用默认的就行 .withHeader(map) .withClaim("uid", UUID.randomUUID().toString()) .withClaim("name", "console") .withExpiresAt(expireTime.getTime()) .sign(algorithm);}
解析token
//加密口令String SECRET = "!Q$#&^&SCMd12";Algorithm algorithm = Algorithm.HMAC256(SECRET);JWTVerifier verifier = JWT.require(algorithm).build();DecodedJWT verify = verifier.verify(token);System.out.println(verify.getHeader());System.out.println(verify.getPayload());System.out.println(verify.getSignature());System.out.println(verify.getClaim("uid").asString());
一个示例util类
public class JwtUtil { private final static String secretKey = "!@S#*&^&%^&BHv*h)dk782GYh"; /** * 加密算法 */ private static Algorithm algorithm = Algorithm.HMAC256(secretKey); /** * 过期时间单位 */ private static int expiresUnit = Calendar.DAY_OF_YEAR; /** * 过期时间值 */ private static int expireAmount = 7; /** * 生成token * @param param payload中携带的数据对 * @return */ public static String generateToken(Mapparam){ JWTCreator.Builder builder = JWT.create(); param.forEach((k,v)->{ builder.withClaim(k,v); }); Calendar instance = Calendar.getInstance(); instance.add(expiresUnit,expireAmount); builder.withExpiresAt(instance.getTime()); String token = builder.sign(algorithm); return token; } /** * 生成token,payload中只有一组信息 * @param key 携带数据的key * @param value 携带数据的值 * @return */ public static String generateToken(String key, String value){ JWTCreator.Builder builder = JWT.create(); Calendar instance = Calendar.getInstance(); instance.add(expiresUnit,expireAmount); builder.withClaim(key,value); builder.withExpiresAt(instance.getTime()); String token = builder.sign(algorithm); return token; } /** * 验证token,验证失败会抛出异常 * @param token 需要验证的token * @return 解码后的token,可以获取写入的值 */ public static DecodedJWT verifyToken(String token){ DecodedJWT decodedJWT = JWT.require(algorithm).build().verify(token); return decodedJWT; }}
拦截器
配置了jwt后,使用拦截器对用户的token进行验证
public class JwtInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Mapmap = new HashMap<>(); String token = request.getHeader("token"); try{ DecodedJWT decodedJWT = JwtUtil.verifyToken(token); //放行 return true; }catch (SignatureVerificationException e){ map.put("msg","无效签名"); }catch (TokenExpiredException e){ map.put("msg","token过期"); }catch (AlgorithmMismatchException e){ map.put("msg","token算法不一致"); }catch (Exception e){ map.put("msg","无效token"); } map.put("status",false); //返回json数据 String json = new ObjectMapper().writeValueAsString(map); response.setContentType("application/json;charset=UTF-8"); response.getWriter().print(json); return false; }}
拦截配置
@Configurationpublic class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new JwtInterceptor()).addPathPatterns("/**").excludePathPatterns("/login","/"); }}
转载地址:https://console.blog.csdn.net/article/details/112688954 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!