背景
feign调用场景中,默认是不会把调用方请求头数据透传到被调用方的,这就容易引起Cookie或Token丢失,引发登录鉴权相关的验证bug。
解决办法
项目里新增个配置类即可,代码如下:
package cn.yiducloud.phs.feign;
import cn.hutool.core.util.StrUtil;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
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;
/**
* @Author: fenghao
* @Description: feign调用配置类,可以透传header里的参数
* @Date: 2022-04-15 11:46:52
**/
@Slf4j
@Configuration
public class FeignConfiguration implements RequestInterceptor {
private final String COOKIE = "Cookie";
private final String TOKEN = "token";
@Override
public void apply(RequestTemplate requestTemplate) {
//获取request
HttpServletRequest request = getHttpServletRequest();
if (request != null) {
//第一种 把header里所有的值都透传,简单粗暴
Map<String, String> headers = getHeaders(request);
for (String headerName : headers.keySet()) {
requestTemplate.header(headerName, getHeaders(getHttpServletRequest()).get(headerName));
}
// //第二种 只针对性的传递想要的header里的值
// String cookie = request.getHeader(COOKIE);
// if (StrUtil.isNotBlank(cookie)) {
// requestTemplate.header(COOKIE, cookie);
// }
// String token = request.getHeader(TOKEN);
// if (StrUtil.isNotBlank(token)) {
// requestTemplate.header(TOKEN, token);
// }
}
}
private HttpServletRequest getHttpServletRequest() {
try {
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
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);
map.put(key, value);
}
return map;
}
}