登录用户信息获取 网关+拦截器+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的工作流程 
			          
			        