1、创建ServletConfig配置类

package com.pn.config;import com.pn.filter.LoginFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.ReactiveRedisTemplate;@Configuration
public class ServletConfig {//0库 博主自己封装的分组redis,可以使用自己的redis@Autowired@Qualifier("reactiveRedisTemplateDb0")private ReactiveRedisTemplate<String, Object> redisTemplate;@Beanpublic FilterRegistrationBean filterRegistrationBean() {//创建ServletRegistrationBean的Bean对象FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();//创建自定义过滤器LoginFilter loginCheckFilter = new LoginFilter();//手动注入redis模板loginCheckFilter.setRedisTemplate(redisTemplate);//将自定义过滤器注册给到filterRegistrationBeanfilterRegistrationBean.setFilter(loginCheckFilter);// 定义拦截的请求filterRegistrationBean.addUrlPatterns("/*");// "/*"所有请求
// filterRegistrationBean.addInitParameter("paramName", "paramValue");// 可以添加参数addInitParameter("k","v")传值return filterRegistrationBean;}
}
2、LoginFilter自定义的过滤器

package com.pn.filter;import com.alibaba.fastjson.JSON;
import com.pn.entity.Result;
import com.pn.utils.WarehouseConstants;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.util.StringUtils;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;public class LoginFilter implements Filter {//将redis模板定义为其成员变量private ReactiveRedisTemplate<String, Object> redisTemplate;//成员变量redis模板的set方法public void setRedisTemplate(ReactiveRedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;}/*** 跨域设置* @param request* @param response*/private void handleCors(HttpServletRequest request, HttpServletResponse response) {response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");response.setHeader("Access-Control-Allow-Headers", "*");response.setHeader("Access-Control-Allow-Credentials", "true");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest)servletRequest;HttpServletResponse response = (HttpServletResponse)servletResponse;// 处理跨域请求handleCors(request, response);if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {response.setStatus(HttpServletResponse.SC_OK);return;}//获取请求url接口String path = request.getServletPath();// 1、白名单直接放行,urlList.add() 放行的apiList<String> urlList = new ArrayList<>();urlList.add("/captcha/captchaImage");urlList.add("/login");urlList.add("/logout");//对static下的/img/upload中的静态资源图片的访问直接放行if(urlList.contains(path)||path.contains("/img/upload")){//放行filterChain.doFilter(request, response);return;}/*** 其他请求带有token,判断redis存的token是否存在*/// 2、拿到前端归还的token,request.getHeader("请求头token字段")String clientToken = request.getHeader(WarehouseConstants.HEADER_TOKEN_NAME);//校验token,校验通过请求放行if(StringUtils.hasText(clientToken)&& Boolean.TRUE.equals(redisTemplate.hasKey(clientToken).block())){//放行filterChain.doFilter(request, response);return;}/*** 其他请求token是否过期,或者没有token的* 校验失败,向前端响应失败的Result对象转成的json串*/Result result = Result.err(Result.CODE_ERR_UNLOGINED, "请登录!");String jsonStr = JSON.toJSONString(result);response.setContentType("application/json;charset=UTF-8");PrintWriter out = response.getWriter();out.print(jsonStr);out.flush();out.close();}
}