后端通过注解进行token校验

不点 阅读:881 2021-04-01 11:08:26 评论:0

1.自定义注解

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
@Documented 
public @interface Login { 
} 

2.拦截器获取并校验token
注:自定义token处理逻辑

@Component 
@Slf4j 
public class AuthorizationInterceptor extends HandlerInterceptorAdapter { 
    @Autowired 
    private JwtUtils jwtUtils; 
 
    public static final String USER_KEY = "userId"; 
 
    @Override 
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 
        Login annotation; 
        if(handler instanceof HandlerMethod) { 
            annotation = ((HandlerMethod) handler).getMethodAnnotation(Login.class); 
        }else{ 
            return true; 
        } 
 
        if(annotation == null){ 
            return true; 
        } 
 
        //获取用户凭证 
        String token = request.getHeader(jwtUtils.getHeader()); 
        if(StringUtils.isBlank(token)){ 
            token = request.getParameter(jwtUtils.getHeader()); 
        } 
 
        //凭证为空 
        if(StringUtils.isBlank(token)){ 
            throw new RRException(jwtUtils.getHeader() + "不能为空", HttpStatus.UNAUTHORIZED.value()); 
        } 
 
        Claims claims = jwtUtils.getClaimByToken(token); 
        if(claims == null || jwtUtils.isTokenExpired(claims.getExpiration())){ 
            throw new RRException(jwtUtils.getHeader() + "失效,请重新登录", HttpStatus.UNAUTHORIZED.value()); 
        } 
 
        //设置userId到request里,后续根据userId,获取用户信息 
        request.setAttribute(USER_KEY, Long.parseLong(claims.getSubject())); 
        log.info("入参:{}",request.getParameterMap()); 
        return true; 
    } 
} 

3.JWTtoken生成、校验

@ConfigurationProperties(prefix = "token.jwt") 
@Component 
public class JwtUtils { 
    private Logger logger = LoggerFactory.getLogger(getClass()); 
 
    private String secret; 
    private long expire; 
    private String header; 
 
    /** 
     * 生成jwt token 
     */ 
    public String generateToken(long userId) { 
        Date nowDate = new Date(); 
        //过期时间 
        Date expireDate = new Date(nowDate.getTime() + expire * 1000); 
 
        return Jwts.builder() 
                .setHeaderParam("typ", "JWT") 
                .setSubject(userId+"") 
                .setIssuedAt(nowDate) 
                .setExpiration(expireDate) 
                .signWith(SignatureAlgorithm.HS512, secret) 
                .compact(); 
    } 
 
    public Claims getClaimByToken(String token) { 
        try { 
            return Jwts.parser() 
                    .setSigningKey(secret) 
                    .parseClaimsJws(token) 
                    .getBody(); 
        }catch (Exception e){ 
            logger.debug("validate is token error ", e); 
            return null; 
        } 
    } 
 
    /** 
     * token是否过期 
     * @return  true:过期 
     */ 
    public boolean isTokenExpired(Date expiration) { 
        return expiration.before(new Date()); 
    } 
 
    public String getSecret() { 
        return secret; 
    } 
 
    public void setSecret(String secret) { 
        this.secret = secret; 
    } 
 
    public long getExpire() { 
        return expire; 
    } 
 
    public void setExpire(long expire) { 
        this.expire = expire; 
    } 
 
    public String getHeader() { 
        return header; 
    } 
 
    public void setHeader(String header) { 
        this.header = header; 
    } 
} 
 

4.配置token有效期

token: 
  jwt: 
    # 加密秘钥 
    secret: f4e2e52034348f86b67cde581c0f9eb5[www.renren.io] 
    # token有效时长,7天,单位秒 
    expire: 604800 
    header: token 

5.Controller方法使用注解验证token

@RestController 
@RequestMapping("/app") 
@Api("APP测试接口") 
public class AppTestController { 
	@Autowired 
	private SysConfigService sysConfigService; 
 
	@Login 
	@GetMapping("userId") 
	@ApiOperation("获取用户ID") 
	public R userInfo(@RequestAttribute("userId") Integer userId) { 
		return R.ok().put("userId", userId); 
	} 
 
	@GetMapping("notToken") 
	@ApiOperation("忽略Token验证测试") 
	public R notToken() { 
		return R.ok().put("msg", "无需token也能访问。。。"); 
	} 
} 
 
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号