登录用户信息获取 网关+拦截器+feign请求添加请求头
给所有请求添加用户身份
微服务获取用户身份
网关已经给所有请求添加了用户身份,也就是authorization头信息。
创建ThreadLocal工具类 :
package com.hmall.order.utils; public class UserHolder { private static final ThreadLocal<Long> tl = new ThreadLocal<>(); public static void setUser(Long userId) { tl.set(userId); } public static Long getUser() { return tl.get(); } public static void removeUser() { tl.remove(); } }
创建拦截器:
package com.hmall.order.interceptor; import com.hmall.order.utils.UserHolder; import org.apache.commons.lang.StringUtils; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @slf4j public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { //1.获取请求头 String authorization = request.getHeader("authorization"); if (StringUtils.isBlank(authorization)) { log.warn("非法用户访问!请求路径:{}",request.getRequestURI()); //没有用户信息,未登录 throw new RuntimeException("用户未登录"); //或者 return false; response.setStatus(403); } //2.转换用户id Long userId = Long.valueOf(authorization); //3.存入ThreadLocal UserHolder.setUser(userId); //4.放行 return true; } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { //用完清理掉 UserHolder.removeUser(); } }
将拦截器注册到SpringMvc,让它生效:
package com.hmall.order.config; import com.hmall.order.interceptor.UserInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class MvcConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { //默认的拦截路径就是/** ,excludePathPatterns()是不用拦截的路径 // registry.addInterceptor(new UserInterceptor()).addPathPatterns("/**").excludePathPatterns(); registry.addInterceptor(new UserInterceptor()); } }
将以上代码(拦截器,config,utils) 放到哪个微服务中,哪个微服务/**路径就会有拦截功能
没有用户信息的请求将会被拦截
给所有有feign的请求,将用户信息添加请求头:
package com.hmall.order.config; import feign.RequestInterceptor; import feign.RequestTemplate; public class MyFeignInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { requestTemplate.header("authorization","2"); } }
配置好后通过路径访问的将被拦截,但是通过网关的就可以访问:
被拦截
可访问
如果想不从网关,实现服务之间调用服务, 将controller层的 被调用的方法开放一个接口到feign.
然后再调用者的启动类添加 :上面的包路径要填写一致
注:(记得导feign的包到服务的pom.xml中)
这样因为feign请求头有用户信息通过feign之间调用服务就不会收拦截
下一篇:
Cookie与Session的工作流程