登录认证(JWT、Filter、Interceptor)

90 阅读4分钟

一、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方法

(四)拦截路径

image.png

四、注册过滤器和拦截器

@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环境中的资源。