龙空技术网

springBoot整合JWT使用

怀揣梦想的码农coder 393

前言:

此时小伙伴们对“spring集成jwt”可能比较关怀,大家都想要剖析一些“spring集成jwt”的相关内容。那么小编也在网上收集了一些关于“spring集成jwt””的相关知识,希望各位老铁们能喜欢,小伙伴们快快来学习一下吧!

注:业余时间自学,以此作为笔记.

JWT数据结构

例如 xxxx.yyy.zzz 由三部分组成,每部分用英文句号连接,JWT的三个部分: header 头部 payload 负载 signature 签名.也就是 Header.Payload.Signature,如图

JWT结构图

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