Spring权限校验JsonWebToken 完整版

​前一段给大家分享了下 关于jwt的生成以及使用,今天抽点时间把完整版的给大家分享出来

话不多说直接上代码 ,关于抛出的异常是我自定义的全局捕获,小伙伴们可以不用管它
1.定义一个java Baen 把它交给spring容器去使用,这样在任何地方就可以注入获取登录后的用户ID和名称了 scope 最简单的理解就是单例
@Component
@Scope(scopeName = "request",proxyMode = ScopedProxyMode.TARGET_CLASS)
public class AuthToken implements Serializable {private Integer adminId;private String userName;}
2.修改JwtUtis工具类
private static final String TOKEN_PREFIX = "Bearer-";
​
JwtBuilder jwtBuilder = Jwts.builder();
       jwtBuilder.setId(id); //唯一ID
       jwtBuilder.setSubject(subject); //主题信息
       jwtBuilder.setIssuer(ISSUER);  //签发者
       jwtBuilder.setIssuedAt(date); //签发时间
       jwtBuilder.setExpiration(expDate);  //过期时间
       jwtBuilder.signWith(signatureAlgorithm, secretKey); //算法及签名秘钥
       return TOKEN_PREFIX + jwtBuilder.compact();
3.解析令牌
public static Claims parseJWT(String jwt){
        try{
            SecretKey secretKey = generalKey();
            return Jwts.parser()
                    .setSigningKey(secretKey)
                    .parseClaimsJws(jwt)
                    .getBody();
        }catch (SignatureException exception){
            throw new BusinessException(AuthEnum.INVALID_TOKEN.getErrorCode(), AuthEnum.INVALID_TOKEN.getErrorMsg());
        }
    }
所有的请求必须都带token才能请求 实现拦截器和忽略掉不用token可以请求的方法。比如说登录,注册
4.自定义拦截器bean
@Component
public class JWTInterceptor extends HandlerInterceptorAdapter {
    @Autowired
    private AuthToken authToken;
    /**
     *简化获取token数据的代码编写(判断是否登录)
     * 1.通过request获取请求token信息
     * 2.从token中解析获取claims
     * 3.将claims绑定到request域中
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//预请求直接通行
        if("OPTIONS".equals(request.getMethod())){
            response.setStatus(HttpServletResponse.SC_OK);
            return true;
        }
        //从头部获取token
        String authorization = request.getHeader("Authorization");
        if (StringUtils.isEmpty(authorization)){
            throw new BusinessException(AuthEnum.NO_AUTH.getErrorCode(),AuthEnum.NO_AUTH.getErrorMsg());
        }
        //去掉token头部,获取完整的jwt信息
        String token = authorization.substring(authorization.indexOf("-") + 1);
        try{
            Claims claims = JwtUtil.parseJWT(token);
            if (claims.isEmpty()){
                throw new BusinessException(AuthEnum.INVALID_TOKEN.getErrorCode(),AuthEnum.INVALID_TOKEN.getErrorMsg());
            }
            Map map = JSON.parseObject(claims.getSubject(), Map.class);
            //过期时间
            long time = claims.getExpiration().getTime();
            //当前时间
            long currentTimeMillis = System.currentTimeMillis();
            if (time < currentTimeMillis){
                throw new BusinessException(AuthEnum.EXP_TOKEN.getErrorCode(),AuthEnum.EXP_TOKEN.getErrorMsg());
            }
            String userName = map.get("username").toString();
            Integer userId = (Integer) map.get("user_id");
            if (StringUtils.isEmpty(userName)){
                throw new BusinessException(AuthEnum.INVALID_TOKEN.getErrorCode(),AuthEnum.INVALID_TOKEN.getErrorMsg());
            }
            //存储用户信息
            authToken.setAdminId(userId);
            authToken.setUserName(userName);
           // request.setAttribute("currentUser", authToken);
            return true;
        }catch (ExpiredJwtException e){
            System.out.println("Token 以过期");
            throw new BusinessException(AuthEnum.EXP_TOKEN.getErrorCode(),AuthEnum.EXP_TOKEN.getErrorMsg());
        }
    }
}
至于request.setAttribute("currentUser", authToken) 这是另一种获取当前用户信息的方法 不方便就不给大家演示了

5.配置拦截器加入spring容器
@Configuration
public class WebConfiguration extends WebMvcConfigurationSupport {
​
​
    @Autowired
    JWTInterceptor jwtInterceptor;
​
​
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(jwtInterceptor).addPathPatterns("/**").
                //设置不拦截的请求地址"/register/**
           excludePathPatterns("/authorization/user/login");
    }
}
excludePathPatterns 就是过滤不拦截的请求,如果有多个就用,逗号隔开就好了

只需要这样就OK了,比如说在添加数据的时候需要获取当前的操作人 ,这个时候就很方便了 只需要在任何想用的时候注入就可以了

@Autowired
private AuthToken authToken

你可能感兴趣的:(java,springboot,spring,jwt,spring,java,spring,boot,令牌环)