Spring Cloud中如何保證各個微服務之間調用的安全性(下篇)

上篇文章 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獲取的

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:

github.com/yinjihuan/s…

更多技術分享請關注微信公衆號:猿天地

image.png
相關文章
相關標籤/搜索