在微服務架構裡,服務與服務之間的呼叫一般用feign就可以實現,它是一種視覺化的rpc,並且整合了ribbon的負載均衡能力,所以很受歡迎。
授權服務
在授權服務裡,使用者通過使用者名稱密碼,或者手機和驗證碼等方式登陸之後,在http頭裡會有授權
的標識,在客戶端呼叫時,需要新增當時有效的token才可以正常訪問被授權的頁面。
Content-Type:application/json
Authorization:Bearer d79c064c-8675-4047-a119-fac692e447e8
而在業務層裡,服務與服務之間使用feign來實現呼叫,而授權的程式碼我們可以通過攔截器實現,在feign請求之前,把當前服務的token新增到目標服務的請求頭就可以了,一般是這樣實現的。
/**
* 傳送FeignClient設定Header資訊.
* http://www.itmuch.com/spring-cloud-sum/hystrix-threadlocal/
* Hystrix傳播ThreadLocal物件
*/
@Component
public class TokenFeignClientInterceptor implements RequestInterceptor {
/**
* token放在請求頭.
*
* @param requestTemplate 請求引數
*/
@Override
public void apply(RequestTemplate requestTemplate) {
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
if (requestAttributes != null) {
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String token = request.getHeader(TokenContext.KEY_OAUTH2_TOKEN);
requestTemplate.header(TokenContext.KEY_OAUTH2_TOKEN,
new String[] {token});
}
}
}
上面的攔截器程式碼沒有什麼問題,也很好理解,但事實上,當你的feign開啟了hystrix功能,如果開啟了,需要把hystrix的策略進行修改,預設是THREAD
的,這個級別時ThreadLocal是空的,所以你的授權不能傳給feign的攔截器.
hystrix.command.default.execution.isolation.strategy: SEMAPHORE
資源專案裡獲取當前使用者
在另一個專案,需要其它獲取當前使用者,需要使用下面的程式碼。
- 先配置一個授權的地址
security:
oauth2:
resource:
id: user
user-info-uri: http://${auth.host:localhost}:${auth.port:8002}/user # 這裡是授權服務的地址,即auth-service
prefer-token-info: false
auth:
host: localhost #這個不可以用eureka裡的服務名,只能使用docker-compose裡的服務名
port: 8002
- 下面的程式碼用來獲取當前使用者
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String user = objectMapper.writeValueAsString(authentication.getPrincipal());
本講主要對feign的請求頭傳遞資訊進行講解,開發時遇到的坑總節了一下,分享給大家!