上篇文章 Spring Cloud中如何保證各個微服務之間調用的安全性 咱們介紹了各個微服務之間調用認證的方式以及原理git
今天咱們繼續接着上篇文章來聊一聊如何可以在調用方實現token的自動設置以及刷新github
咱們的認證token是放在請求頭中的,相對於把token放在請求參數中更爲友好,對業務接口無侵入性spring
可是這種方式若是須要本身設置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));
}
複製代碼
或者下面這種方式bash
/**
* 獲取房產信息
* @param houseId 房產編號
* @return
*/
@GetMapping("/")
public ResponseData hosueInfo(Long houseId,String token) {
return ResponseData.ok(houseService.getHouseInfo(houseId));
}
複製代碼
若是是PathVariable這種方式,參數是必傳的,否則沒法進入接口內,若是是RequestParam這種方式,方法中不定義token參數,我估計也是能夠的,至少不會報錯,反正咱們是統一的去判斷有無權限微信
因此說咱們的token放在請求頭中,是很是友好的併發
在調用接口的時候怎麼往請求頭中添加token呢?app
每次調用的地方都去添加token是否是太煩了?ide
其實在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獲取的
/**
* 定時刷新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:
更多技術分享請關注微信公衆號:猿天地