Feign请求拦截器错误拼接请求头名与值致401问题解决
Feign拦截器添加请求头时值包含头名称导致401未授权的解决方法
在使用Spring Boot 2.5.9 + Spring Cloud Feign 1.4.7.RELEASE时,通过Feign拦截器添加认证令牌和租户ID请求头,请求后端接口时收到401未授权错误:
feign.FeignException$Unauthorized: [401] during [POST] to [http://xxxxx/api/files/files] [FilesClient#upload(String,MultipartFile,String)]
调试发现请求头的值中被拼接了请求头名称,导致认证令牌无效。
问题原因
- 版本不兼容:Spring Boot 2.5.9对应的Spring Cloud版本应为2020.0.x(Ilford),而你使用的
spring-cloud-starter-feign 1.4.7.RELEASE属于老旧的Edgware版本,两者版本跨度大,存在兼容性问题,可能导致Feign处理请求头的逻辑异常。 - 请求头添加方式不当:使用
requestTemplate.headers(headers)批量添加请求头时,旧版本Feign对Map格式的请求头处理存在bug,导致头名称被错误拼接到值中。
解决方案
步骤1:修复依赖版本(关键)
废弃老旧的spring-cloud-starter-feign,改用官方推荐的spring-cloud-starter-openfeign,并匹配Spring Boot 2.5.9对应的版本:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> <!-- Spring Boot 2.5.x对应Spring Cloud 2020.0.x,指定兼容版本 --> <version>3.0.5</version> </dependency>
注:若项目已引入Spring Cloud依赖管理,可省略版本号,由dependencyManagement自动匹配对应版本。
步骤2:修改Feign拦截器的请求头添加方式
放弃批量添加的方式,改用requestTemplate.header()方法逐个添加请求头,避免Map处理的潜在问题:
@Slf4j @Component public class FeignRequestInterceptor implements RequestInterceptor{ @Override public void apply(RequestTemplate requestTemplate) { // 逐个添加请求头,参数依次为头名称、头值 requestTemplate.header(Constants.AUTH_HEADER, Access.token()); requestTemplate.header(Constants.X_TENANT_ID, Access.getCurrentTenant()); log.info("Feign拦截器已添加认证和租户请求头"); } }
额外优化:规范Feign客户端的请求头参数
你的Feign客户端中@RequestHeader String path未指定头名称,默认会将参数名path作为头名称,建议明确指定以避免歧义:
@FeignClient(name = "files", url = "${feign.clients.files.url}") public interface FilesClient { @PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE) FileUploadResponse upload(@RequestPart("file") MultipartFile file, @RequestParam("fileName") String fileName, // 明确指定请求头名称 @RequestHeader("path") String path); }
内容的提问来源于stack exchange,提问作者ErisoHV
相关产品推荐
相关产品推荐

