說明: access_token: 服務端與客戶端通信,有時服務端需要知道客戶端的身份,就會用到access_token來用於驗證身份。 refresh_token: 但為了保證安全token會設置過期時間,如果直接過期,相當於用戶或調用端正在使用產品,突然間就退出登錄了,這種產品體驗很差,於是有了 ...
說明:
access_token: 服務端與客戶端通信,有時服務端需要知道客戶端的身份,就會用到access_token來用於驗證身份。
refresh_token: 但為了保證安全token會設置過期時間,如果直接過期,相當於用戶或調用端正在使用產品,突然間就退出登錄了,這種產品體驗很差,於是有了refresh_token。
簡易流程: 登錄後,服務端返回兩個token,用於確定身份的access_token(短時間過期),和刷新access_token的refresh_token(長時間過期),請求介面時,如果access_token未過期則正常使用;當access_token過期但refresh_token未過期,則使用refresh_token獲取新的access_token;如果refresh_token過期,則本次會登錄過期,退出。
反對理由:
安全形度:
濫用問題: refresh_token是用來生成新的access_token而生的(字面意思叫刷新令牌),所以它就像一個token機關槍一樣,突突突可以生成任意多個access_token,現在黑客攻擊花樣層出不窮,所以這個refresh_token因各種攻擊或漏洞泄露出去很不安全。
全局鑒權問題 若有邏輯漏洞,用戶主動退出登錄致使access_token1銷毀,能不能保證這個refresh_token創建的access_token_2也失去作用呢,顧頭也得顧腚。
開發角度:
實現繁瑣: 就一個登錄還要兩個token,雖然不複雜,但是繁瑣。
存儲問題: token是不用存儲,但是為了安全,用戶退出時access_token未過期,則需要在服務端存儲一個黑名單,如果服務端在遇見這個access_token則直接拒絕這次訪問。並附加一個過期時間,這個過期時間設置的一般是略大於或等於
access_token的過期時間,access_token需要這個解決方案,那麼refresh_token也需要解決,數據量小還好,數量大這又是個問題。
產品角度:
這是個概率問題,也是個矛盾問題,就要看開發者怎麼實現了,如果refresh_token和asscess_token過期直接退出登錄,則用戶可能正在使用或剛剛在用,然後會話就突然退出登錄了,產品體感很差。
如果開發者考慮到refresh_token自動續期,那麼都續期,refresh_token是不是又顯得多餘?是不是一個access_token自動續期就行了?
解決方案:就一個access_token即可。
續期問題怎麼辦?
現在很多access_token都用jwt,token裡面可以塞一些數據,其中一個就是過期時間,伺服器處理數據前,可在服務端判斷token是否臨近過期,如果臨近過期直接自動生成新的access_token等邏輯處理完成,一併返回,客戶端無感知靜默續期,如果不用jwt,使用自定義token生成策略,原理也差不多。
續期的邊界問題怎麼辦?
例如token過期時間30分鐘,用戶在21分鐘和31分鐘做了請求,服務端設置自動續期的時間點是>=25分鐘,此時token又沒有自動續期,用戶在31分鐘時仍舊會退出登錄,用戶體驗還是不好。解決方案有兩個,token距離過期時間的閾值設置的大一點,比如設置20分鐘,這樣可以自動續期避免邊界問題。二是讓前端解析token(一般是jwt),每分鐘執行一次,前端檢測到token塊過期了,非同步請求介面自動續期,只要前端能解析,是否快過期了客戶端最清楚。
安全問題呢?
濫用問題不存在。
全局鑒權問題,仍舊需要讓服務端把未過期但棄用的token放入黑名單中,並設置過期時間。
開發問題呢?
一個token相對簡單。
存儲問題:仍舊需要讓服務端把未過期但棄用的token放入黑名單中,並設置過期時間,該存的還得存。
產品問題呢?
做好自動續期,用戶體感就好了。
總結:
可見access_token也不是完美的,但相比refresh_token更方便也更安全,也確實難以找出一種完美的解決方案。