在做接口请求时,我们经常会在header头中增加一些鉴权信息,如token 或 jwt,那么在通过fegin从A server去调用B server的接口时,如果B server的接口需要header信息,我们需要将A sever获取的header转发到B上。

解决方式

我们需要实现Feign提供的一个接口 RequestInterceptor

@Configuration
public class FeignAutoConfiguration implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate){
        if (null == getHttpServletRequest()) {
            // 此处省略日志记录
            return;
        }
        // 将获取Header对应的值往下面传
        Map<String, String> headersMap = getHeaders(getHttpServletRequest());
        if (headersMap != null && headersMap.size() > 0) {
            Set<Entry<String, String>> entrySet = headersMap.entrySet();
            for (Entry<String, String> entry : entrySet) {
                String key = entry.getKey();
                String value = entry.getValue();
                // Authorization //headersMap.get("Authorization")
                requestTemplate.header(key, value);
            }

        }
    }

    private HttpServletRequest getHttpServletRequest() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * Feign拦截器拦截请求获取对应的值
     *
     * @param request
     * @return
     */
    private Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap<>();
        Enumeration<String> enumeration = request.getHeaderNames();
        while (enumeration.hasMoreElements()) {
            String key = enumeration.nextElement();
            String value = request.getHeader(key);
            // 跳过 content-length
            if (key.equals("content-length")){
                continue;
            }
            map.put(key, value);
        }
        return map;
    }
}

Q.E.D.


知道的越多,不知道的越多