使用Feign設置Token鑒權調用接口
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<String, Object> 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<String, Object> map = new HashMap<>();
? ? ? ? map.put("user_id", "xxx");
? ? ? ? map.put("password", "xxxxx");
? ? ? ? //調用 T 具體對象具體封裝?
? ? ? ? MetaDataResponseVO<T> login = feignTest.login(map);
? ? ? ? List<T> data = login.getData();
? ? ? ? System.out.println(login.getData());
? ? ? ? //處理業(yè)務data
? ? }
}返回對象可以封裝demo
@Data
public class MetaDataResponseVO<T> implements Serializable {
? ? private static final long serialVersionUID = 316492198399615153L;
? ? /**
? ? ?* 狀態(tài)碼.
? ? ?*/
? ? private String retcode;
? ? /**
? ? ?* 狀態(tài)碼描述.
? ? ?*/
? ? private String retmsg;
? ? /**
? ? ?* 響應包體.
? ? ?*/
? ? private List<T> data;
}設置token 進行調用,F(xiàn)eign 的請求攔截器來統(tǒng)一添加請求頭信息
先去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;
? ? }
? ? /**
? ? ?* 創(chuàng)建 Feign 請求攔截器, 在發(fā)送請求前設置認證的 Token, 各個微服務將 Token 設置 到環(huán)境變量中來達到通用的目的
? ? ?*
? ? ?* @return
? ? ?*/
? ? @Bean
? ? public FeignBasicAuthRequestInterceptor basicAuthRequestInterceptor() {
? ? ? ? return new FeignBasicAuthRequestInterceptor();
? ? }
}上面的準備好之后,我們只需要在調用業(yè)務接口之前先調用認證接口,然后將獲取到的 Token 設置到環(huán)境變量中,通過 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 signInMetaData() {
? ? ? ? //拿緩存
? ? ? ? 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;
/**
?* 無限極元數(shù)據接口.
?*
?* @author 林志鵬
?* @date 2021/5/7
?*/
@FeignClient(name = "metaDataClient", url = "${feign-client.meta-data.url}", configuration = MetaDataFeignConfig.class)
public interface MetaDataClient {
? ? /**
? ? ?* 拉取物理系統(tǒng)列表.
? ? ?*/
? ? @RequestMapping(value = "/sc/mtdsystemlist", method = RequestMethod.GET)
? ? MetaDataResponseVO<MetaDataSystem> pullPhysicalSystemList();我們在調用該業(yè)務接口時候,需要先去調用設置頭信息feign,在調用業(yè)務feign。
?/**
? ? ?* 拉取物理系統(tǒng)列表.
? ? ?*
? ? ?* @return
? ? ?*/
? ? public List<MetaDataSystem> pullPhysicalSystem() {
? ? ? ? //鑒權feign
? ? ? ? signInMetaData();
? ? ? ? //業(yè)務feign
? ? ? ? MetaDataResponseVO<MetaDataSystem> responseVO = metaDataClient.pullPhysicalSystemList();
? ? ? ? if (Objects.nonNull(responseVO)) {
? ? ? ? ? ? List<MetaDataSystem> data = responseVO.getData();
? ? ? ? ? ? if (Objects.nonNull(data) && !data.isEmpty()) {
? ? ? ? ? ? ? ? return data;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return new ArrayList<>();
? ? }補充
經過測試 鑒權接口調用成功,但是業(yè)務接口返回竟然超過10s feign默認的返回1秒就會觸發(fā)熔斷機制,所以我們需要設置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,然后在業(yè)務中調用feignClient時,通過新加一個feign攔截器,攔截feign請求,把當前的header中的token添加到feign的請求頭中去。實現(xiàn)token在鏈路中的傳遞。
具體實現(xiàn)
新增 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
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
SpringBoot中使用Cookie實現(xiàn)記住登錄的示例代碼
這篇文章主要介紹了SpringBoot中使用Cookie實現(xiàn)記住登錄的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07
DynamicDataSource怎樣解決多數(shù)據源的事務問題
這篇文章主要介紹了DynamicDataSource怎樣解決多數(shù)據源的事務問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07

