09-OpenFeign-令牌中继、透传

在一般发送请求的过程中,我们会在请求Header中添加参数信息,如token认证、全局事物id、链路追踪的logid等。

但是使用openfeign后,默认不支持传递header头信息。

因此,需要借助额外的配置,让请求的Header中的参数令牌在微服务链路调用中传递下去,保证各个微服务能够获取令牌中的用户信息。

注意:openFeign在开启熔断降级后内部调用开启了子线程,因此传统的方案直接在RequestInterceptor中设置是不可行的。

RequestContextHolder内部通过InheritableThreadLocal实现子线程共享信息。

在FeignCircuitBreakerInvocationHandler这个类中也是有如下一行代码:

RequestContextHolder.setRequestAttributes(requestAttributes);

 以下通过实现RequestInterceptor拦截器,读取请求中的参数信息,放入feign的RequestTemplate中,实现透传功能。


import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;

@Component
public class OpenFeignConfig implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) { 
        //从RequestContextHolder中获取HttpServletRequest
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //获取RequestContextHolder中的信息
        Map headers = getHeaders(request);
        //放入feign的RequestTemplate中
        for (Map.Entry entry : headers.entrySet()) {
            template.header(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 获取原请求头
     */
    private Map getHeaders(HttpServletRequest request) {
        Map map = new LinkedHashMap<>();
        Enumeration enumeration = request.getHeaderNames();
        if (enumeration != null) {
            while (enumeration.hasMoreElements()) {
                String key = enumeration.nextElement();
                String value = request.getHeader(key);
                map.put(key, value);
            }
        }
        return map;
    }
}

你可能感兴趣的:(OpenFeign,令牌中继,透传)