token拦截以及参数校验
token拦截
参考
SpringBoot集成JWT实现token验证
springboot基于token实现登录认证
Springboot项目中使用过滤器Filter+ThreadLocal实现对请求用户的拦截和保存
三个结合起来,构造过程:
添加依赖——自定义注解——自定义工具类JwtUtils——自定义UserUtils——自定义拦截器——配置拦截器——请求测试
添加依赖
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
JWT讲解+自定义注解
《SpringBoot集成JWT实现token验证》讲的很细
自定义工具类JwtUtils
参考《springboot基于token实现登录认证》的JwtUtils,token有时效性
由于其解析token可能发生很多的异常,参考《Jwt实现token创建与解析,异常处理》
所以改一下解析token的方法:
/**
* 解析token,可得到claim
*/
public static Claims getClaimByToken(String token) {
try {
return Jwts.parser()
.setSigningKey(secret)
.parseClaimsJws(token)
.getBody();
}catch (ExpiredJwtException ex){
throw new RrException(30002,"token已过期!");
}
catch (RuntimeException e){
throw new RrException(30000,"token解析异常!");
}
}
这里抛出的异常参考 springboot 如何优雅的抛出异常
自定义拦截器
《SpringBoot集成JWT实现token验证》讲的很细
执行顺序就是:查看是否映射到方法——查看是否有权限注释——从header中查看是否有token(可抛出token不存在异常)——解析token(可能抛出过期或解析失败异常)——token解析得到id取数据库查看是否有该用户(可抛出不存在用户异常)——存储token中的id等信息。
存储token中的id等信息:
自定义UserUtils
由于token中包含的id等信息可能会在验证完token之后进行操作时,需要该信息。因此在拦截器验证完token没抛出异常,则要存储部分需要的信息。
参考《Springboot项目中使用过滤器Filter+ThreadLocal实现对请求用户的拦截和保存》
配置拦截器
《SpringBoot集成JWT实现token验证》讲的很细
请求测试
参数校验
优雅的校验参数-javax.validation
@Validated和@Valid区别
综上,post请求,请求数据为json用@Valid,get请求用@Validated
校验参数后需要处理抛出的异常,在此处理的操作放在里上一篇
MyControllerAdvice
/**
* 普通参数(非 java bean)校验出错时抛出,返回answerret对象给前端 @Validated
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(value = ConstraintViolationException.class)
public AnswerRet errorHandler1(ConstraintViolationException ex) {
AnswerRet<String> answerRet=new AnswerRet(10001,ex.getMessage());
return answerRet;
}
/**
* 请求参数绑定到java bean上失败时抛出,返回answerret对象给前端 @Valid
* @param ex
* @return
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public AnswerRet bindExceptionHandler(BindException ex){
if(ex.hasErrors()){
AnswerRet answerRet=new AnswerRet();
List<FieldError> list = ex.getFieldErrors();
StringBuffer sb = new StringBuffer("参数:");
for(FieldError error : list){
sb.append(error.getField()).append(",");
}
sb.append("不符合要求");
answerRet.setCode(10001);
answerRet.setMsg(sb.toString());
return answerRet;
}
return new AnswerRet(10000, "系统繁忙!");
}
post请求
引入依赖+使用
效果
get请求
get请求大多都是接口都是非 java bean 参数的校验,则用 spring的@Validated注解
@Validated给Controller注释一下就可以使用了
效果