Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

拦截器

张先生 edited this page Aug 24, 2020 · 3 revisions

拦截器

作用:拦截用户登录认证以及权限

1. AdminAuthInterceptor 后台用户权限验证
2. AdminTokenInterceptor 后台用户登录token验证
3. FrontTokenInterceptor 移动端用户登录token验证
4. SwaggerInterceptor Swagger登录验证
  1. PC后台访问除过一下接口,其余必须验证登录操作
 1、登录
 2、验证码
 3、后台登录页面轮播图、LOGO
  1. 移动端会有三种情况
 1、必须登录;用户中心、下单等接口
 2、不需要登录;商品列表,首页接口等;
 3、如果登录则取用户信息,否则不取,根据用户信息给出的数据不相同;优惠券接口
  1. 如何配置以上三种情况,请仔细阅读以下代码
package com.zbkj.crmeb.config;
import com.filter.ResponseFilter;
import com.interceptor.AdminAuthInterceptor;
import com.interceptor.AdminTokenInterceptor;
import com.interceptor.FrontTokenInterceptor;
import com.interceptor.SwaggerInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.MappedInterceptor;
//token验证拦截器
@Configuration
public class WebConfig implements WebMvcConfigurer {
 // 这里使用一个Bean为的是可以在拦截器中自由注入,也可以在拦截器中使用SpringUtil.getBean 获取
 // 但是觉得这样更优雅
 //后台用户权限
 @Bean
 public HandlerInterceptor adminAuthInterceptor(){
 return new AdminAuthInterceptor();
 }
 //后台用户登录
 @Bean
 public HandlerInterceptor adminTokenInterceptor(){
 return new AdminTokenInterceptor();
 }
 //移动端用户登录
 @Bean
 public HandlerInterceptor frontTokenInterceptor(){
 return new FrontTokenInterceptor();
 }
 @Bean
 public ResponseFilter responseFilter(){ return new ResponseFilter(); }
 @Value("${swagger.basic.username}")
 private String username;
 @Value("${swagger.basic.password}")
 private String password;
 @Value("${swagger.basic.check}")
 private Boolean check;
 @Override
 public void addInterceptors(InterceptorRegistry registry) {
 //添加token拦截器
 //addPathPatterns添加需要拦截的命名空间;
 //excludePathPatterns添加排除拦截命名空间
 //后台token拦截
 registry.addInterceptor(adminTokenInterceptor()).
 addPathPatterns("/api/admin/**").
 excludePathPatterns("/api/admin/validate/**");
 //后台权限规则
 registry.addInterceptor(adminAuthInterceptor()).
 addPathPatterns("/api/admin/**").
 excludePathPatterns("/api/admin/validate/**");
 //前端用户登录token
 registry.addInterceptor(frontTokenInterceptor()).
 addPathPatterns("/api/front/**").
 excludePathPatterns("/api/front/qrcode/**");
 }
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
 registry.addResourceHandler("/**")
 .addResourceLocations("classpath:/static/");
 registry.addResourceHandler("swagger-ui.html")
 .addResourceLocations("classpath:/META-INF/resources/");
 registry.addResourceHandler("/webjars/**")
 .addResourceLocations("classpath:/META-INF/resources/webjars/");
 }
 @Bean
 public FilterRegistrationBean filterRegister()
 {
 //注册过滤器
 FilterRegistrationBean registration = new FilterRegistrationBean(responseFilter());
 registration.addUrlPatterns("/*");
 return registration;
 }
 /* 必须在此处配置拦截器,要不然拦不到swagger的静态资源 */
 @Bean
 @ConditionalOnProperty(name = "swagger.basic.enable", havingValue = "true")
 public MappedInterceptor getMappedInterceptor() {
 return new MappedInterceptor(new String[]{"/swagger-ui.html", "/webjars/**"}, new SwaggerInterceptor(username, password, check));
 }
}
  1. 针对2.3如何处理?
1、不做任何配置,让FrontTokenInterceptor来拦截
2、在FrontTokenInterceptor做部分路由判断;判断路由,部分路由不管用户是否登录都可以访问
3、看下面核心代码;在CheckFrontToken.checkRouter里配置路由即可
package com.interceptor;
import com.alibaba.fastjson.JSONObject;
import com.common.CheckFrontToken;
import com.common.CommonResult;
import com.utils.RequestUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//token验证拦截器
public class FrontTokenInterceptor implements HandlerInterceptor {
 @Autowired
 private CheckFrontToken checkFrontToken;
 //程序处理之前需要处理的业务
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
 response.setCharacterEncoding("UTF-8");
 String token = checkFrontToken.getTokenFormRequest(request);
 if(token == null || token.isEmpty()){
 //判断路由,部分路由不管用户是否登录都可以访问
 boolean result = checkFrontToken.checkRouter(RequestUtil.getUri(request));
 if(result){
 return true;
 }
 response.getWriter().write(JSONObject.toJSONString(CommonResult.unauthorized()));
 return false;
 }
 Boolean result = checkFrontToken.check(token, request);
 if(!result){
 response.getWriter().write(JSONObject.toJSONString(CommonResult.unauthorized()));
 return false;
 }
 return true;
 }
 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {}
 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex){}
}
package com.common;
import com.constants.Constants;
import com.utils.RedisUtil;
import com.utils.RequestUtil;
import com.utils.ThreadLocalUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/**
 * 检测token是否过期
 * Created on 2019年11月23日
 * @author zhangle
 */
@Component
public class CheckFrontToken {
 @Autowired
 protected RedisUtil redisUtil;
 public Boolean check(String token, HttpServletRequest request){
 try {
 boolean exists = redisUtil.exists(Constants.USER_TOKEN_REDIS_KEY_PREFIX + token);
 if(exists){
 Object value = redisUtil.get(Constants.USER_TOKEN_REDIS_KEY_PREFIX + token);
 Map<String, Object> hashedMap = new HashMap<>();
 hashedMap.put("id", value);
 ThreadLocalUtil.set(hashedMap);
 redisUtil.set(Constants.USER_TOKEN_REDIS_KEY_PREFIX +token, value, Constants.TOKEN_EXPRESS_MINUTES, TimeUnit.MINUTES);
 }else{
 //判断路由,部分路由不管用户是否登录/token过期都可以访问
 exists = checkRouter(RequestUtil.getUri(request));
 }
 return exists;
 }catch (Exception e){
 return false;
 }
 }
 //路由在此处,则返回true,无论用户是否登录都可以访问
 public boolean checkRouter(String uri) {
 String[] routerList = {
 "api/front/product/detail",
 "api/front/coupons",
 "api/front/index"
 };
 return ArrayUtils.contains(routerList, uri);
 }
 public String getTokenFormRequest(HttpServletRequest request){
 return request.getHeader(Constants.HEADER_AUTHORIZATION_KEY);
 }
}

Clone this wiki locally

AltStyle によって変換されたページ (->オリジナル) /