上篇文章 Spring Cloud中如何保證各個微服務之間呼叫的安全性 我們介紹了各個微服務之間呼叫認證的方式以及原理
今天我們繼續接著上篇文章來聊一聊如何能夠在呼叫方實現token的自動設定以及重新整理
我們的認證token是放在請求頭中的,相對於把token放在請求引數中更為友好,對業務介面無侵入性
但是這種方式如果需要自己設定token就麻煩了,如果是引數的形式,那麼在呼叫的時候就把獲取的token當做引數傳就可以了
House getHouseInfo(Long id, String token);
複製程式碼
傳參的方式不好的就是每個介面需要增加一個引數的定義
/**
* 獲取房產資訊
* @param houseId 房產編號
* @return
*/
@GetMapping("/{houseId}/{token}")
public ResponseData hosueInfo(@PathVariable("houseId")Long houseId,@PathVariable("token")String token) {
return ResponseData.ok(houseService.getHouseInfo(houseId));
}
複製程式碼
或者下面這種方式
/**
* 獲取房產資訊
* @param houseId 房產編號
* @return
*/
@GetMapping("/")
public ResponseData hosueInfo(Long houseId,String token) {
return ResponseData.ok(houseService.getHouseInfo(houseId));
}
複製程式碼
如果是PathVariable這種方式,引數是必傳的,不然無法進入介面內,如果是RequestParam這種方式,方法中不定義token引數,我估計也是可以的,至少不會報錯,反正我們是統一的去判斷有無許可權
所以說我們的token放在請求頭中,是非常友好的
接下來我們說說使用的問題
在呼叫介面的時候怎麼往請求頭中新增token呢?
每次呼叫的地方都去新增token是不是太煩了?
其實在Zuul中我們可以用過濾器來統一新增token,這個時候可以使用置前的過濾器pre
**
* 呼叫服務前新增認證請求頭過濾器
*
* @author yinjihuan
* @create 2017-11-07 16:06
**/
public class AuthHeaderFilter extends ZuulFilter {
public AuthHeaderFilter() {
super();
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulRequestHeader("Authorization", TokenScheduledTask.token);
return null;
}
}
複製程式碼
這樣在每個請求轉發到具體的微服務之前,我們給它新增了token資訊,這個token資訊是我們從TokenScheduledTask獲取的
TokenScheduledTask是怎麼獲取token的呢?
/**
* 定時重新整理token
*
* @author yinjihuan
* @create 2017-11-09 15:39
**/
@Component
public class TokenScheduledTask {
private static Logger logger = LoggerFactory.getLogger(TokenScheduledTask.class);
public final static long ONE_Minute = 60 * 1000 * 60 * 20;
public static String token = "";
@Autowired
private AuthService authService;
/**
* 重新整理Token
*/
@Scheduled(fixedDelay = ONE_Minute)
public void reloadApiToken() {
token = authService.getToken();
while (StringUtils.isBlank(token)) {
try {
Thread.sleep(1000);
token = authService.getToken();
} catch (InterruptedException e) {
logger.error("", e);
}
}
}
}
複製程式碼
原來是一個定時任務,通過呼叫認證的方法來獲取認證好的token
##為什麼要做成定時的呢
如果按照一般的做法那就是請求之後都去獲取一次token, 這種方式是最不好的,效能太差
稍微好點那就是在獲取的地方加上快取,貌似不錯,但是有個問題是在併發的時候會存在N個請求去獲取token,這邊需要控制下
定時的就不存在上面的問題了,但是一定要確保定時任務的正常
我這邊一個token的失效時間為24小時,所以我這邊重新整理的間隔是20小時,也就是說在token還沒過期之前,我會自動重新整理成最新的,這樣就不會出現token過期的問題了
while迴圈是為了確保token能夠正確的重新整理成功
同時這個任務是在專案啟動之後立馬去重新整理token的,這樣就能確保剛過來的請求不會受到影響
具體程式碼可以參考我的github:
更多技術分享請關注微信公眾號:猿天地