3、访问权限控制(拦截器)

业务需求

当用户没有登录条件下.不允许访问购物车/订单/支付/物流等相关涉密操作.
如何实现:

  • AOP: 主要实现了业务层解耦.但是无法直接获取request/response对象
  • 拦截器: 由于需要通过url地址判断用户是否有权限.所以拦截器是首选.

实现思路

利用SpringMVC的拦截器.判断用户是否登录.

  • 如果用户已经登录则拦截器放行用户请求.同时将用户信息传递到后端使所有服务都能进行访问
  • 如果用户没有登录,应该重定向到用户登录页面.

拦截器工作原理及实现

3、访问权限控制(拦截器)_第1张图片
拦截器

@Component
public class UserInterceptor implements HandlerInterceptor {
	//redis集群
	@Autowired
	private JedisCluster jedisCluster;
	//服务调用之前拦截判断
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		//获取cookie,拿到token
		Cookie[] cookies = request.getCookies();
		String token = null;
		for (Cookie cookie : cookies) {
			if ("JT_TICKET".equals(cookie.getName())) {
				token = cookie.getValue();
				break;
			}
		}
		//验证缓存中是否存在有效token
		if (!StringUtils.isEmpty(token)) {
			String userInfo = jedisCluster.get(token);
			if (!StringUtils.isEmpty(userInfo)) {
				User user = ObjectMapperUtil.toObject(userInfo, User.class);
//				request.setAttribute("JT_USER", user);
				//自定义封装ThreadLocal传递用户信息
				UserThreadLocal.set(user);
				return true;
			}
		}
		//若token无效则重定向到登录页面
		response.sendRedirect("/user/login.html");
		return false;
	}
	//服务执行之后,拦截执行
	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
		UserThreadLocal.remove();
	}
}

拦截器配置

@Configuration
public class MvcConfigurer implements WebMvcConfigurer {

	@Autowired
	private UserInterceptor userInterceptor;

	//开启匹配后缀型配置
	@Override
	public void configurePathMatch(PathMatchConfigurer configurer) {
		configurer.setUseSuffixPatternMatch(true);
	}
	//	/* 只能拦截下一级路径 
	//  /** 拦截所有的路径
	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(userInterceptor).addPathPatterns("/cart/**","/order/**");
	}
}

ThreadLocal传递用户信息工具类

public class UserThreadLocal {
	private static ThreadLocal<User> userThreadLocal = new ThreadLocal<>();

	public static void set(User user) {
		userThreadLocal.set(user);
	}

	public static User get() {
		return userThreadLocal.get();
	}

	public static void remove() {
		userThreadLocal.remove();
	}
}

动态获取当前登录用户id信息

你可能感兴趣的:(微服务,拦截器)