需求描述
在微服务项目中,需要请求第三方接口,通常情况下我们使用 spring 的 restTemplate。但接触到 feign 之后,这种将远程方法伪装成本地接口,屏蔽请求感知的方式,无疑更优雅。
但对于 oauth 认证,需要配置请求头,即设置 feign 的自定义配置。
自定义授权头信息
请求远程连接
@FeignClient
用于注册接口为 feign 客户端,在 spring cloud 项目中,需要在其 value(或 name)属性中指定对应的微服务名,url 置空(将自动匹配配置中西地址)。当需要调用任意的 http 请求时,只要给定 url 值即可。
注意 :此时,虽然不是请求微服务接口,仍然需要设置 name,填写任意(不冲突的)名称即可。
授权流程
授权配置
需要通过自定义配置属性来指定请求头,对应 @FeignClient
的 configuration 属性。
该属性指定一个自定义配置类,用于设置 feign 的任意配置。
Basic 认证
1 2 3 4 5 6 7 8 9 10 11 12 13
|
public class SomeAuthConfig {
@Bean public BasicAuthRequestInterceptor basicAuthRequestInterceptor(SomeProperties someProperties) { return new BasicAuthRequestInterceptor( someProperties.getAuth().getUser(), someProperties.getAuth().getPassword() ); } }
|
请求 token
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @FeignClient( name = "some-auth", url = "${some.auth.url}", configuration = SomeAuthConfig.class ) public interface SomeAuthIntegration {
@PostMapping(value = "/xxx") SomeAuthResponse getToken();
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class SomeTokenConfig {
@Bean public RequestInterceptor requestInterceptor(SomeAuthIntegration authIntegration) { return requestTemplate -> { SomeAuthResponse authResponse = authIntegration.getToken(); requestTemplate.header( AUTHORIZATION, StrUtil.format("{} {}", authResponse.getTokenType(), authResponse.getAccessToken()) ); }; } }
|
已授权请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @FeignClient( name = "some-reply", url = "${some.reply.url}", configuration = SomeTokenConfig.class ) public interface SomeReplyIntegration {
@PostMapping("/xxx") void apply(SomeStatus status);
}
|
自定义解码器
当响应信息实际返回的是 json 格式,但头信息描述类型是 Content-Type: text/xml;charset=utf-8 (或其他非 *application/json *类型)时,feign 的默认消息转换器无法解析,此时就需要重新使用自定义解码器。
在配置类中注册 Decoder bean。
1 2 3 4 5 6 7 8 9 10
| @Bean public Decoder someResponseDecoder() { return new SpringDecoder(() -> new HttpMessageConverters( new MappingJackson2HttpMessageConverter() { { setSupportedMediaTypes(Lists.newArrayList(MediaType.TEXT_XML)); } } )); }
|
其他
feing 基于 http 请求,在其配置类中,可以实现任意 http 的相关配置,包括超时时间、重试次数等。
一般情况下,accessToken 存在过期时间,为了防止频繁请求授权,应该在过期之前进行缓存。