中國有句老話, 既生瑜何生亮, 既然有我周瑜在世, 為什麼老天還要一個諸葛亮啊?
同樣的, 眾所周知, 在 OAuth 2.0 授權協議中, 也有兩個令牌 token , 分別是 access_token 和 refresh_token, 為什麼已經有了 access_token, 還需要 refresh_token 呢?
我們先看下面兩者的介紹
- access_token
訪問令牌, 它是一個用來訪問受保護資源的憑證 - refresh_token
重新整理令牌, 它是一個用來獲取access token的憑證
下面是 OAuth 2.0 中的 token 工作流程圖
迴歸主題,
這兩個令牌的主要區別如下:
-
access_token 時效短, refresh_token 時效長, 比如 access_token 有效期1個小時, refresh_token 有效期1天
-
access_token 是授權伺服器一定頒發的, 而 refresh_token 卻是可選的
-
access_token 過期後, 可以使用 refresh_token 重新獲取, 而 refresh_token 過期後就只能重新授權了, 也沒有 refresh_refresh_token
-
access_token 和 資源伺服器和授權伺服器互動, 而 refresh_token 只和 授權伺服器互動
-
access_token 頒發後可以直接使用, 而使用 refresh_token 需要客戶端祕鑰 client_secret
接下來, 我們繼續看兩個令牌在下面場景的應用, 假設有一個使用者需要在後臺管理介面上操作6個小時。
1 頒發一個有效性很長的 access_token, 比如 6 個小時, 或者可以更長, 這樣使用者只需要剛開始登入一次, access_token 可以一直使用, 直到 access_token 過期, 然後重複, 這種是不安全的, access_token 的時效太長, 也就失去了本身的意義。
2 頒發一個1小時有效期的 access_token, 過期後重新登入授權, 這樣使用者需要登入 6 次, 安全倒是有了, 但是使用者體驗極差
3 頒發1小時有效期的 access_token 和6小時有效期的 refresh_token, 當 access_token 過期後(或者快要過期的時候), 使用 refresh_token 獲取一個新的 access_token, 直到 refresh_token 過期, 使用者重新登入, 這樣整個過程中,使用者只需要登入一次, 使用者體驗好。
access_token 洩露了怎麼辦? 沒關係, 它很快就會過期。
refresh_token 洩露了怎麼辦? 沒關係, 使用 refresh_token 是需要客戶端祕鑰 client_secret 的。
4 使用者登入後, 在後臺管理頁面上操作1個小時後, 離開了一段時間, 然後 5個小時後, 回到管理頁面繼續操作, 此時 refresh_token 有效期6個小時, 一直沒有過期, 也就可以換取新的 access_token, 使用者在這個過程中, 可以不用重複登入。但是在一些安全要求較高的系統中, 第二次操作是需要重新登入的, 即使 refresh_token 沒有過期, 因為中間有幾個小時, 使用者是沒有操作的, 系統猜測使用者已離開, 並關閉會話。
所以, 得出的結論是, refresh_token 是一個很巧妙地設計, 提升了使用者體驗的同時, 又保證了安全性。
另外, 在 OAuth 2.0 安全最佳實踐中, 推薦 refresh_token 是一次性的, 什麼意思呢? 使用 refresh_token 獲取 access_token 時, 同時會返回一個 新的 refresh_token, 之前的 refresh_token 就會失效, 但是兩個 refresh_token 的絕對過期時間是一樣的, 所以不會存在 refresh_token 快過期就獲取一個新的, 然後重複,永不過期的情況。