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;
@Bean
public FilterRegistrationBean filterRegistrationBean() {
//创建ServletRegistrationBean的Bean对象
FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
//创建自定义过滤器
LoginFilter loginCheckFilter = new LoginFilter();
//手动注入redis模板
loginCheckFilter.setRedisTemplate(redisTemplate);
//将自定义过滤器注册给到filterRegistrationBean
filterRegistrationBean.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");
}
@Override
public 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() 放行的api
List<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();
}
}