Spring拦截器简化用户token验证和角色验证
在服务中定义拦截器类
这里创建用户会生成密码,然后用BCryptPasswordEncoder生成乱码存于数据库。
而登录操作会根据登录用户的id,用户名,和角色三个串生成令牌。
登录后以后用户进行这个服务的其他操作就要在头文件携带令牌才能够通过拦截器的验证了。
一首先要向框架注册拦截器存在,这里使用拦截器的配置类
springboot不提供配置文件xml,只能写配置类,因为拦截器springboot并不默认配置,所以需要写配置类。
配置类主要继承WebMvcConfigrationSupport接口,里面提供了addInterceptors的方法(规范)
//注册拦截器:声明拦截器对象()和要拦截的uri路径是声明
package com.tensquare.eureka.user.config;
import com.tensquare.eureka.user.interceptor.JwtInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
////springboot不再有web.xml配置,只能写一个拦截器的类
//@Component
//@Configuration
//public class InterceptorConfig extends WebMvcConfigurationSupport {
// @Autowired
// private JwtInterceptor jwtInterceptor;//获得整个拦截器,进行拦截
// @Override
// protected void addInterceptors(InterceptorRegistry registry){
// //注册拦截器要声明拦截器对象和要拦截的请求(拦截器是谁,拦截器要干什么)
// registry.addInterceptor(jwtInterceptor)
// .addPathPatterns("/**")//拦截所有路径
// .excludePathPatterns("/**/login/**");//但不拦截login登录的路径
//
// }
//
//}
@Component
@Configuration
public class InterceptorConfig extends WebMvcConfigurationSupport {
@Autowired
private JwtInterceptor jwtInterceptor;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")//先设置拦截器的路径,再特别放行/**/login/**的请求
.excludePathPatterns("/**/login/**");
}
}
二、定义拦截器的具体操作内容
拦截器的接口HandlerInterceptor有3个方法,将default改成public
这里主要使用pre(aop知识)。
package com.tensquare.eureka.user.interceptor;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import util.JwtUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//JwtInterceptor实现了拦截器的其中一个功能,但是它需要一些基础配置,写在了interceptorconfig里
@Component//扔进容器
//拦截器负责解析token,放行所有
public class JwtInterceptor implements HandlerInterceptor {
@Autowired
private JwtUtil jwtUtil;
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("经过了拦截器");
//无论如何都放行,具体能不能操作还是在具体的操作中去判断
//拦截器只是负责把请求头中包含token的令牌进行一个解析验证
String header=request.getHeader("Authorization");
if(header!=null && !"".equals(header)){
//如果有包含有Authorization头信息,就对其进行解析
if(header.startsWith("Bearer ")){
//得到token
String token =header.substring(7);//从第7位网后截
//对令牌进行验证
try {
Claims claims=jwtUtil.parseJWT(token);//在生成token的时候本身就是将角色作为关键字生成的
String roles=(String)claims.get("roles");
if(roles!=null&&roles.equals("admin")){//用户不存在或者角色不是admin
request.setAttribute("claims_admin",token);
}
if(roles!=null&&roles.equals("user")){
request.setAttribute("claims_user",token);
}
} catch (Exception e) {
throw new RuntimeException("令牌不正确");
}
}
}
return true;//return true放行,return false不让往下走
}
}
配置了拦截器以后,只要请求抵达到controller,
那么因为拦截器中
if(roles!=null&&roles.equals("admin")){//用户不存在或者角色不是admin
request.setAttribute("claims_admin",token);
}
if(roles!=null&&roles.equals("user")){
request.setAttribute("claims_user",token);
}
在request里面定义了一个键值对属性,这个键值对