前言:
此时小伙伴们对“spring集成jwt”可能比较关怀,大家都想要剖析一些“spring集成jwt”的相关内容。那么小编也在网上收集了一些关于“spring集成jwt””的相关知识,希望各位老铁们能喜欢,小伙伴们快快来学习一下吧!注:业余时间自学,以此作为笔记.
JWT数据结构
例如 xxxx.yyy.zzz 由三部分组成,每部分用英文句号连接,JWT的三个部分: header 头部 payload 负载 signature 签名.也就是 Header.Payload.Signature,如图
1、Header 头部
是一个JSON 对象, 描述JWT的元数据,例如: {"alg": "HS256", "typ": "JWT"}
alg属性表示签名的算法(algorithm),默认是 HMAC SHA256
typ属性表示这个令牌的类型(type),JWT 令牌统一写为JWT,不写则默认上面格式
2、payload 负载
是一个JSON 对象, 用来存放实际需要传递的数据,形如: {"sub": "1234567890", "name": "John Doe","admin": true}
一般是在这个部分定义私有字段: 例如{"userId":"1","userName":"jack"}
注意,JWT 默认是不加密的,任何人都可以读到,所以不要把机密信息放在这个部分,如用户密码等。
3、signature 签名
signature 是对前两部分的签名,防止数据篡改
1、需要指定一个密钥(secret) 2、这个密钥只有服务器才知道,不能泄露给客户端 3、使用 Header 里面指定的签名算法,按照下面的公式产生签名
jwt认证流程图
springBoot整合JWT1、首先写一个jwt工具类
public class JwtHelper { // 加密字符串,随便定义 private static final String SECRET = "@su_shui_feng@"; // 签发人 private static String ISSUER = "sys_user"; // 期限 15d public static final long EXPIRE_SECONDS = 15 * 24 * 60 * 60; /** * 生成JWT * * @return */ public static String getToken(UserInfo userInfo) { try { //使用HMAC256进行加密 Algorithm algorithm = Algorithm.HMAC256(SECRET); LocalDateTime localDateTimeNow = LocalDateTime.now(); LocalDateTime localDateTimeExpire = localDateTimeNow.plusSeconds(EXPIRE_SECONDS); //token过期时间 Date expire = Date.from(localDateTimeExpire.atZone(ZoneId.systemDefault()).toInstant()); //创建jwt String token = JWT.create() .withClaim("userId", userInfo.getUserId()) .withClaim("userName", userInfo.getUsername()) .withClaim("role", userInfo.getRole()) .withIssuer(ISSUER) // 发行人 .withExpiresAt(expire) .sign(algorithm);// 过期时间点 return token; } catch (IllegalArgumentException e) { throw new RuntimeException(e); } } /** * 解密jwt */ public static UserInfo parseToken(String token) { UserInfo user = null; try { JWTVerifier verifier = JWT.require(Algorithm.HMAC256(SECRET)).withIssuer(ISSUER).build(); DecodedJWT jwt = verifier.verify(token); Map<String, Claim> claimMap = jwt.getClaims(); Map<String, String> userMap = new HashMap<>(); claimMap.forEach((k, v) -> userMap.put(k, v.asString())); user = BeanUtil.mapToBean(userMap, UserInfo.class, true); } catch (Exception e) { e.printStackTrace(); } return user; }}2、登录时获取token
public Rest<UserInfo> loginApp(@RequestParam(value = "data") String data) throws IOException { HashMap<String, Object> paramMap = JSONUtil.toBean(data, HashMap.class); UserInfo userInfo = systemAppService.getLoginInfo(paramMap); if (userInfo != null) { String token = JwtHelper.getToken(userInfo); userInfo.setToken(token); Map config = new HashMap(); config.put("socketAddress", propertyConfig.getSocketAddress()); config.put("allocurl", propertyConfig.getAllocurl()); userInfo.setConfig(config); return RestUtil.ok(userInfo); } return RestUtil.fail("用户名或密码不正确"); }3、拦截器,拦截头部没有携带token的接口
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // System.out.println("app login intercept ..."); log.info("app login intercept used ..."); // 从 http 请求头中取出 token final String token = request.getHeader("token"); // 如果不是映射到方法直接通过 if (!(handler instanceof HandlerMethod)) { return true; } HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); // 检查是否有passtoken注释,有则跳过认证 if (method.isAnnotationPresent(PassToken.class)) { PassToken passToken = method.getAnnotation(PassToken.class); if (passToken.required()) { return true; } } // 执行认证 if (StringUtils.isEmpty(token)) { // 未登录,返回401 response.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } // 解析token UserInfo userInfo = JwtHelper.parseToken(token); if (userInfo == null) { // 抛出异常,证明未登录,返回401 response.setStatus(HttpStatus.UNAUTHORIZED.value()); return false; } // 放入线程域 UserLocal.set(userInfo); return true; }4、配置拦截器
@Configurationpublic class CustomMVCConfiguration implements WebMvcConfigurer { //拦截器 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AppLoginInterceptor()) .addPathPatterns("/**") //拦截所有路径 .excludePathPatterns("/system/loginApp") //放行登录接口 .excludePathPatterns("/doc.html", "/swagger-resources/**"); }}5、结束
标签: #spring集成jwt