视频软件App开发引领数字内容创作与分享的新时代
1421
2022-10-21
使用Feign设置Token鉴权调用接口
目录Feign设置Token鉴权调用接口声明FeignClient指定url调用测试返回对象可以封装demo先去implementsRequestInterceptor重写apply方法配置-Feign调用进行Token鉴权项目场景解决办法具体实现注意有Bug!!!
Feign设置Token鉴权调用接口
声明FeignClient 指定url
/**
* CREATE BY songzhongjin ON 2021.05.08 15:58 星期六
* DESC:feign方式 测试Deom
*/
@FeignClient(name = "testService", url = "http://xxxxxx:8088")
public interface FeignTest {
/**
* 通过feign调用接口
* @param map
* @return
*/
@PostMapping(value = "/xxxxx/sys/login")
String login(Map
}
调用测试
/**
* CREATE BY songzhongjin ON 2021.05.08 16:02 星期六
* DESC:
*/
@RestController
public class Test {
@Autowired
FeignTest feignTest;
@Autowired
MetaDataService metaDataService;
@PostMapping("/test")
public void test() {
HashMap
map.put("user_id", "xxx");
map.put("password", "xxxxx");
//调用 T 具体对象具体封装
MetaDataResponseVO
List
System.out.println(login.getData());
//处理业务data
}
}
返回对象可以封装demo
@Data
public class MetaDataResponseVO
private static final long serialVersionUID = 316492198399615153L;
/**
* 状态码.
*/
private String retcode;
/**
* 状态码描述.
*/
private String retmsg;
/**
* 响应包体.
*/
private List
}
设置token 进行调用,Feign 的请求-来统一添加请求头信息
先去implements RequestInterceptor 重写apply方法
/**
* feign-配置,调用前先鉴权.
*/
@Component
public class MetaDataFeignConfig implements RequestInterceptor {
public FeignBasicAuthRequestInterceptor() {
}
/**
* 给feign请求加上accessToken请求头.
*
* @param template
*/
@Override
public void apply(RequestTemplate template) {
//feign加请求头 自定义fangjia.auth.token"
template.header("access_token", System.getProperty("fangjia.auth.token"));
}
}
配置-
-需要在 Feign 的配置中定义,代码如下所示。
@Configuration
public class FeignConfiguration {
/**
* 日志级别
*
* @return
*/
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
/**
* 创建 Feign 请求-, 在发送请求前设置认证的 Token, 各个微服务将 Token 设置Tdktq 到环境变量中来达到通用的目的
*
* @return
*/
@Bean
public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new FeignBasicAuthRequestInterceptor();
}
}
上面的准备好之后,我们只需要在调用业务接口之前先调用认证接口,然后将获取到的 Token 设置到环境变量中,通过 System.setProperty(“fangjia.auth.token”,token) 设置值,可以使用redis存放避免每次调用。
@Value("${feign-client.meta-data.user}")
private String userId;
@Value("${feign-client.meta-data.password}")
private String password;
private static final String METADATA_ACCESS_TOKEN = "metaDataAccessToken";
/**
* 获取token,设置到上下文.
*/
public void shttp://ignInMetaData() {
//拿缓存
String accessToken = redisUtils.get(METADATA_ACCESS_TOKEN);
log.warn("-----------从redis拿meta的token结果--token ={}-------------", accessToken);
//System.setProperty("fangjia.metadata.token",token) 设置token值
System.setProperty("feign.metadata.token", accessToken);
log.warn("--------------设置metaData接口鉴权结束-----------------");
}
token设置完成,我们需要在我们其他的feign文件中配置这个token,
注意配置对应的-configuration ,MetaDataFeignConfig.class这个类就是我们设置头信息的
@FeignClient(name = “metaDataClient”, url = “${feign-client.meta-data.url}”, configuration = MetaDataFeignConfig.class)
package com.infinitus.dmm.openapi;
/**
* 无限极元数据接口.
*
* @author 林志鹏
* @date 2021/5/7
*/
@FeignClient(name = "metaDataClient", url = "${feign-client.meta-data.url}", configuration = MetaDataFeignConfig.class)
public interface MetaDataClient {
/**
* 拉取物理系统列表.
*/
@RequestMapping(value = "/sc/mtdsystemlist", method = RequestMethod.GET)
MetaDataResponseVO
我们在调用该业务接口时候,需要先去调用设置头信息feign,在调用业务feign。
/**
* 拉取物理系统列表.
*
* @return
*/
public List
//鉴权feign
signInMetaData();
//业务feign
MetaDataResponseVO
if (Objects.nonNull(responseVO)) {
List
if (Objects.nonNull(data) && !data.isEmpty()) {
return data;
}
}
return new ArrayList<>();
}
补充
经过测试 鉴权接口调用成功,但是业务接口返回竟然超过10s feign默认的返回1秒就会触发熔断机制,所以我们需要设置feign的超时时间,可以指定FeignClient 名name 很人性化。
@FeignClient(name = “metaDataClient”, url = “${feign-client.meta-data.url}”)
#给metaDataClient服务设置超时时间 这里metaDataClient是我自己,全局的话metaDataClient替换default
feign:
client:
config:
metaDataClient:
connect-timeout: 50000
read-timeout: 50000
hystrix:
enabled: false
Feign调用进行Token鉴权
项目场景
这边使用 两个springboot应用,中间通过feign来进行远程调用(是的没错,架构就是这么奇葩)。然后在调用feign的时候,希望可以进行token鉴权。
解决办法
请求进来时,通过-,校验header的token,然后在业务中调用feignClient时,通过新加一个feign-,拦截feign请求,把当前的header中的token添加到feign的请求头中去。实现token在链路中的传递。
具体实现
新增 feign -配置
/**
* Feign请求-配置.
*
* @author linzp
* @version 1.0.0
* @date 2021/4/16 21:19
*/
@Configuration
public class FeignInterceptorConfig implements RequestInterceptor {
public FeignInterceptorConfig() {}
@Override
public void apply(RequestTemplate template) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//设置token到请求头
template.header(ConstantCommon.HEADER_TOKEN_KEY, request.getHeader(ConstantCommon.HEADER_TOKEN_KEY));
}
}
然后在feignClient接口中,添加 == configuration = FeignInterceptorConfig.class==
注意有Bug!!!
注意!!!,这里会有个异常,获取到的request会是null。原因是hytrix隔离策略是thread,无法读到 threadLocal变量。
解决办法!!更改策略
在配置文件中新增如下配置,即可解决!
# 更换hystrix策略,解决无法传递threadLocal变量问题
hystrix:
command:
default:
execution:
isolation:
strategy: SEMAPHORE
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~