SpringBoot的Filter过滤器结合JWT实现登录验证
概念:Filter 过滤器,是 JavaWeb 三大组件(Servlet、Filter、Listener)之一。
过滤器可以把对资源的请求拦截下来,从而实现一些特殊的功能。
过滤器一般完成一些通用的操作,比如:登录校验、统一编码处理、敏感字符处理等。
快速入门
定义FIlter类
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("初始化方法");Filter.super.init(filterConfig);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("放行前执行的逻辑");filterChain.doFilter(servletRequest,servletResponse);System.out.println("放行后执行的逻辑");}@Overridepublic void destroy() {System.out.println("销毁方法执行的逻辑");Filter.super.destroy();}
}
配置Filter
Filter类上加 @WebFilter 注解,配置拦截资源的路径。
引导类上加 @ServletComponentScan 开启Servlet组件支
@SpringBootApplication
@ServletComponentScan
public class WebManagementApplication {public static void main(String[] args) {SpringApplication.run(WebManagementApplication.class, args);}}
Filter拦截路径
拦截具体路径 |
/login |
只有访问 /login 路径时,才会被拦截 |
目录拦截 |
/emps/* |
访问/emps下的所有资源,都会被拦截 |
拦截所有 |
/* |
访问所有资源,都会被拦截 |
Filter的执行流程:请求 --> 放行前逻辑 --> 放行 --> 资源 --> 放行后逻辑
过滤器链: 一个web应用中,配置了多个过滤器,就形成了一个过滤器链
登录验证Filter流程
- 获取请求url。
- 判断请求url中是否包含login,如果包含,说明是登录操作,放行。
- 获取请求头中的令牌(token)。
- 判断令牌是否存在,如果不存在,返回错误结果(未登录)。
- 解析token,如果解析失败,返回错误结果(未登录)
- 放行
Filter类
@Slf4j
@WebFilter(urlPatterns = "/*")
public class TestFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;httpServletResponse.setCharacterEncoding("UTF-8");//获取urlString url = httpServletRequest.getRequestURI();log.info("url:{}",url);//判断是否包含login请求,是就放行if (url.contains("login")) {filterChain.doFilter(request,response);return;}//获取tokenString token = httpServletRequest.getHeader("token");//判断token是否存在if (!StringUtils.hasLength(token)) {Result error = Result.error("未登录");String noLogin = JSONObject.toJSONString(error);httpServletResponse.getWriter().write(noLogin);return;}//解析token是否存在try {JwtUtils.parseJwt(token);}catch (Exception e){e.printStackTrace();Result noLogin = Result.error("未登录");String s = JSONObject.toJSONString(noLogin);httpServletResponse.getWriter().write(s);return;}log.info("令牌合法,放行:{}",token);filterChain.doFilter(request,response);}
}
JwtUtils类
@Component
public class JwtUtils {private static final String SIGN_KEY = "laohuang";//生成public static String generateJwt(Map<String,Object> claims){return Jwts.builder().setClaims(claims) //自定义内容.signWith(SignatureAlgorithm.HS256, SIGN_KEY)//签名算法.setExpiration(new Date(System.currentTimeMillis() + 12 * 3600)) //有效期.compact();}//解析public static Claims parseJwt(String token){return Jwts.parser().setSigningKey(SIGN_KEY).parseClaimsJws(token).getBody();}
}
结果