一、JWT令牌
(一)简介
JWT全称:JSON Web Token
作用:将JSON数据进行安全的封装,可以进行安全的信息传输。
组成:
1.header(头):记录令牌的类型与算法。
2.Payload(载荷):一些自定义信息与默认信息。
3.Signature(签名):防止Token被篡改、确保安全性;将header、payload,并加入指定密钥,通过指定算法计算而来。进行base64编码。
(二)生成
1.首先要导入JWT依赖。
<!--JWT依赖-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
2.使用提供的JWT工具类来生成或解析令牌。
可以通过setExpiration来设置令牌的生效时间
```
public class JwtUtils {
private static String signKey = "SVRIRUlNQQ==";
private static Long expire = 1000*60*60L;
/**
* 生成JWT令牌
* @return
*/
public static String generateJwt(Map<String,Object> claims){
String jwt = Jwts.builder()
.addClaims(claims)
.signWith(SignatureAlgorithm.HS256, signKey)
.setExpiration(new Date(System.currentTimeMillis() + expire))
.compact();
return jwt;
}
/**
* 解析JWT令牌
* @param jwt JWT令牌
* @return JWT第二部分负载 payload 中存储的内容
*/
public static Claims parseJWT(String jwt){
Claims claims = Jwts.parser()
.setSigningKey(signKey)
.parseClaimsJws(jwt)
.getBody();
return claims;
}
}
(三)注意
1.JWT校验时使用的签名密钥,必须和生成的JWT令牌配套
2.如果JWT解析或校验时报错,则说明JWT令牌被篡改或是失效,令牌非法。
二、过滤器(Filter)
(一)什么是Filter
- Filter是过滤器,是JavaWeb三大组件(servlet,filter,listener)之一。
- 表示可以把资源的请求拦截下来,使用了过滤器之后,想要访问服务器上的内容,必须要先经过过滤器,过滤器处理完毕之后才可以访问对应的资源。
- 通常用来完成一些通用的功能,比如登录校验、统一编码处理、敏感字符处理等等。
(三)Filter使用步骤
1.先定义一个类来实现Filter接口,实现其方法。
2.配置Filter,在Filter类上添加一个@WebFilter注解,并配置拦截路径。
3.在引导类上添加一个@ServletComponentScan注解开启Servlet组件支持。
```
//实现类
@WebFilter(urlPatterns = "/*")
public class DemoFilters implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// Filter.super.init(filterConfig);
System.out.println("=================初始化=====================");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("==================开始执行filter=====================");
System.out.println("===================开始拦截====================");
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("==================拦截后=====================");
}
@Override
public void destroy() {
Filter.super.destroy();
System.out.println("==============执行结束==============");
}
}
//引导类
@ServletComponentScan
@SpringBootApplication
@MapperScan(basePackages = "com.ithiema.boottlias.mapper")
public class BootTliasApplication {
public static void main(String[] args) {
SpringApplication.run(BootTliasApplication.class, args);
}
}
4.注意:
- 如果过滤器中不执行放行操作,过滤器拦截到请求之后,就不会访问对应的资源。
- 放行:filterChain.doFilter(servletRequest,servletResponse)
(三)执行流程
- 1.首先获取请求url。
- 2.判断url是否包含login的路径,如果包含,说明需要是登录操作放行。
- 3.不包含,则获取请求头中的令牌(token)。
- 4.判断令牌是否存在,如果不存在,响应401。
- 5.解析token令牌,如果解析失败,响应401。
- 6.放行。
过滤前的代码 ----> 放行(目标资源)---> 过滤后的代码
(四)拦截路径
- 拦截具体路径 —— /login —— 只有访问/login路径时,才会被拦截
- 目录拦截 —— /emps/* —— 访问/emps下的所有资源都会被拦截
- 拦截所有 —— /* ——访问所有路径都会被拦截
(五)过滤器链
在一个web中,可以配置多个过滤器,多个过滤器就形成了一个过滤器链。
顺序:注解配置的Filter,优先级是按过滤器的类名自然排序。
三、拦截器(Interceptor)
(一)介绍
1.概念:是一种动态拦截方法的调用,类似于过滤器。是spring提供,用来拦截控制器的方法执行。
2.作用:拦截请求,在指定的方法调用前后,根据业务需要求执行预先的设定。
(二)使用步骤
1.首先定义一个拦截器,实现HandlerInterceptor接口,并实现其方法(preHandle、postHandle、afterCompletion)。
2.注册拦截器
@Component
public class DemoInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("handler执行前执行");
// ture: 表示放行 false:表示拦截
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("handler执行后,渲染视图前执行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("渲染视图后执行,释放一些资源");
}
}
(三)执行流程
- 1.首先获取请求url。
- 2.判断url是否包含login的路径,如果包含,说明需要是登录操作放行。
- 3.不包含,则获取请求头中的令牌(token)。
- 4.判断令牌是否存在,如果不存在,响应401。
- 5.解析token令牌,如果解析失败,响应401。
- 6.放行。
preHandle 方法中的 ---> 放行(目标资源)---> postHandle方法 ---> afterCompletion方法
(四)拦截路径
四、注册过滤器和拦截器
@Configuration //表示当前类是一个Spring的配置类
public class ConFig implements WebMvcConfigurer {
// 过滤器
@Autowired
private AuthorizedFilter authorizedFilter;
// 拦截器
@Autowired
private AuthorizedInterceptor authorizedInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册过滤器
registry.addInterceptor(authorizedFilter)
.addPathPatterns("/**");
// 注册拦截器
registry.addInterceptor(authorizedInterceptor)
.addPathPatterns("/**").excludePathPatterns("/login");
}
}
五、Filter 与 Interceptor 区别
1.接口规范不同,过滤器需要实现Filter接口,而拦截器需要实现HandlerInterceptor接口。
2.拦截的范围不同,过滤Filter会拦截所有的资源,而Interceptor只会拦截spring环境中的资源。