常見的鑑權方式有兩種,一種是基於session,另外一種是基於token方式的鑑權,咱們來淺談一下兩種 鑑權方式的區別。java
業界經常使用的受權標準有兩種,一種是使用auth2,這種方式更適合於相似第三方受權登陸,好比微信、微博、QQ信任登陸業務。另外一種是oauth,即第三方無需知道用戶和密碼就能夠申請得到該資源的受權,更適用於對用戶的權限校驗並分配訪問權限,好比常見的登陸後分配可見資源(按鈕、菜單等)類型網站。redis
Javashop電商系統 採用的是oauth方式的鑑權標準。咱們以系統的應用爲例來介紹oauth的方案。spring
1. 登陸
服務端校驗密碼,成功後返回access_token和refresh_token,客戶端記錄上述token。
2. 訪問API
在訪問API以前解析access_token,而且查看是否過時,若是不過 期則請求API,若是過時,則要刷新令牌,在請求API。
3. 刷新token
攜帶有效期的refresh_token換回有效token,若是refresh_token過時,則須要用戶從新登陸。
4. 註銷
請求註銷api,服務器端和客戶端應同時刪除token的存儲。api
1. 客戶端請求API
攜帶access_token信息,若是生成環境不會直接攜帶access_token,會使用加密後的簽名校驗。祥見如下防重放機制。
2. 獲取token
根據環境不一樣而有不一樣的獲取token方式。
3. 解析token
經過JWT工具將token解析。
4. 由redis讀取token
根據uid拼接key讀取access_token, 若是不存在這個用戶的token說明已經登出。
5. 驗證token
判斷次token是否屬於此uid,判斷token是否過時,若是過時則進行如下刷新token的流程。
6. 注入權限
若是token驗證成功,根據user信息生成權限注入到spring安全上下文中。瀏覽器
刷新token流程安全
1. 客戶端請求API
攜帶refresh_token,若是是生產環境不會直接攜帶refresh_token信息,詳見如下防重放攻擊。
2. 獲取token
根據環境不一樣而有不一樣的獲取token方式。
3. 解析token
經過JWT工具將token解析。
4. token讀取
根據uid拼接key讀取出access_token,若是不存在這個用戶的token說明用戶已經登出。
5. 驗證token
判斷此token是否屬於此uid,判斷token是否已通過期,若是過時,則返回refresh_token過時錯誤,此時用戶須要從新登陸。
6. 刷新token
若是refresh_token 驗證成功,則從新生成access_token和refresh_token,上述有效期以當前時間向後計算,替換此用戶在redis中的token,並將token返回給客戶端。服務器
1、 參數的讀取
1. 在生產環境時,不能直接傳遞token,而是要傳遞簽名數據,服務器端驗籤後由Redis中獲取簽名。
2. 若是是非生產環境,直接由header中讀取token。
2、 生產環境傳遞以下參數
memberid (用戶id)
nonce(隨機字串,6位)
timestamp(當前時間戳,到秒)
sign= md5( uid+ nonce + timestamp +token )
3、 驗證邏輯
1. 驗證時間戳
判斷時間戳是否起過60s,大於60s則判別爲重放攻擊。微信
2. 驗證nonce
首先驗證nonce在 reids中是否存在,若是存在,則判別爲重放攻擊,不然將nonce記錄在redis中(key爲:"nonce"+uid+"_"+nonce),失效時間爲60s。
3. 驗證sign
md5( uid+ nonce + timestamp +token ) 驗證是簽名是否經過。
4. 驗證token
經過uid拿到token ,驗證邏輯同驗權流程。cookie
固然在不一樣的業務場景下實現方案是多種多樣的,僅以此方案拋磚引玉,供你們參考。 session
易族智匯(javashop)原創文章