使用Feign设置Token鉴权调用接口

网友投稿 836 2022-08-20


使用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 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 = new HashMap<>();

map.put("user_id", "xxx");

map.put("password", "xxxxx");

//调用 T 具体对象具体封装

MetaDataResponseVO login = feignTest.login(map);

List data = login.getData();

System.out.println(login.getData());

//处理业务data

}

}

返回对象可以封装demo

@Data

public class MetaDataResponseVO implements Serializable {

private static final long serialVersionUID = 316492198399615153L;

/**

* 状态码.

*/

private String retcode;

/**

* 状态码描述.

*/

private String retmsg;

/**

* 响应包体.

*/

private List data;

}

设置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 pullPhysicalSystemList();

我们在调用该业务接口时候,需要先去调用设置头信息feign,在调用业务feign。

/**

* 拉取物理系统列表.

*

* @return

*/

public List pullPhysicalSystem() {

//鉴权feign

signInMetaData();

//业务feign

MetaDataResponseVO responseVO = metaDataClient.pullPhysicalSystemList();

if (Objects.nonNull(responseVO)) {

List data = responseVO.getData();

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小时内删除侵权内容。

上一篇:子线程任务发生异常时主线程事务回滚示例过程
下一篇:Springboot 内部服务调用方式
相关文章

 发表评论

暂时没有评论,来抢沙发吧~