OAuth 的運作方式——授權碼流程

OAuth 的運作方式,畫在一張互動畫布上:用戶、用戶端應用程式、授權伺服器與資源伺服器之間的授權碼流程。

OAuth 讓一個應用程式代表用戶存取另一個服務的資料,而全程都不會看到用戶的密碼——它用一次同意授權,換取一個有效期很短的權杖。

OAuth 的運作方式——授權碼流程

The interactive FlowJam canvas for this explanation — every lane, row and arrow above is a real QueryChart diagram you can open and edit.

How to read this visual

  • 由左至右讀這三個直欄:授權、權杖交換、受保護資源。
  • 每一列是其中一方在整個故事裡的部分——用戶那一列在最上,資源伺服器那一列在最下,於是用戶的同意授權與伺服器的驗證,把中間的一切夾在其中。
  • 跨列的箭頭,例如授權碼回到用戶端那一支,是各方之間真實的網絡訊息;留在同一列之內的箭頭,是那一方自己的步驟。

同意授權的來回

流程由用戶那一列開始——用戶按下「使用供應商帳戶登入」——然後交接到「用戶端把用戶重新導向至授權伺服器」。這次重新導向是 OAuth 最具決定性的一步:它把用戶帶離用戶端應用程式,送到供應商那邊,而「用戶登入並批准所請求的授權範圍」就在那裡發生。真正重要的是同意授權畫面,而不只是登入本身:用戶在這裡明確選擇用戶端可以做甚麼。「授權伺服器把授權碼回傳給用戶端」把控制權交還應用程式,但交還的只是一個授權碼,不是權杖。

權杖交換

「用戶端用授權碼與自己的密鑰換取存取權杖」由用戶端那一列跨進授權伺服器那一列。在這一步,用戶端同時出示收到的授權碼與已註冊的 client secret,藉此證明自己是一個合法的應用程式——所以單單偷到一個授權碼並不足夠。「授權伺服器簽發存取權杖」就是同意授權的決定變成一種能力的一刻:一串字,說明用戶端可以做甚麼,以及可以做多久。

把權杖花掉

「用戶端帶著存取權杖呼叫資源伺服器」跨進「資源伺服器」群組,而「資源伺服器驗證權杖並回傳用戶的資料」就是回報。資源伺服器從來看不到用戶的密碼,也看不到同意授權畫面——它只檢查權杖。「用戶在應用程式內看到自己的資料」在用戶那一列把整個環扣上:在用戶眼中,他們只是登入了一次,然後應用程式就拿到了他們的資料。

Key relationships and takeaways

  • 用戶的密碼只會交給授權伺服器——用戶端與資源伺服器從來看不到它。
  • 同意授權(也就是那些授權範圍)才是真正的授予;存取權杖只是這個授予的機器可讀形式。
  • 授權碼有效期很短,而且沒有 client secret 就毫無用處——兩個因素一起保護這次交換。
  • 存取權杖會到期;更新權杖會靜靜換出新的權杖,不需要再出現一次同意授權畫面。
  • 資源伺服器唯一的工作就是驗證權杖,而這正是各方得以保持解耦的原因。

When to use this visual

  • 向產品團隊解釋為甚麼「使用 Google 帳戶登入」是安全的,以及同意授權畫面到底在問甚麼。
  • 選擇一種 OAuth 流程:這裡的授權碼流程,相對於其他情境所用的隱含式流程或 client credentials 流程。
  • 審視在你的整合裡,用戶憑據與權杖實際上會經過哪些地方。

運作方式

  1. 把各方改名為你的系統

    把這四個群組換成你真實的參與者——你的網頁應用程式、你的身分供應商、你的 API——讓那些邊界反映你正在記錄的那個系統。

  2. 加上你所請求的授權範圍

    在同意授權那一步標註實際的授權範圍,以及每一項為甚麼需要,好讓覆核的人看得到最小權限的取捨。

  3. 畫出更新權杖的路徑

    在權杖到期之後加一條分支:用戶端出示更新權杖,換取一個新的存取權杖,過程中不會出現同意授權畫面,最後以它自己明確的狀態結束。

  4. 把失敗情況也畫出來

    加上拒絕的分支——被拒絕的同意授權畫面、無效的授權碼、已到期或已撤銷的權杖——每一條都連著它所產生的錯誤回應。

常見問題

甚麼是 OAuth?它為甚麼存在?

OAuth 是一套委託標準。它讓一個應用程式代表用戶存取另一個服務上的資料,而應用程式全程都看不到用戶的密碼。用戶在授權伺服器驗證一次身分,並批准特定的權限(授權範圍);應用程式收到一個可以花用的權杖。這種職責分離,正是這張圖解裡四個群組所代表的東西。

授權碼與存取權杖有甚麼分別?

授權碼是用戶同意授權之後、用戶端收到的一個有效期很短的中間值;它本身不授予任何東西。用戶端要用這個授權碼——連同已註冊的 client secret——去換取存取權杖,而存取權杖才是真正用來呼叫資源伺服器的能力。這個兩步交換,正是用戶端可以在權杖端點證明自己身分的原因。

為甚麼用戶不把密碼交給應用程式?

因為應用程式只需要有限而且可以撤銷的存取權——讀取一份個人檔案,而不是擁有一個帳戶。如果應用程式拿到密碼,它就會永遠擁有全部存取權,而用戶亦無法在不到處更改密碼的情況下單獨撤銷其中一個應用程式。OAuth 用一個範圍受限、會到期、而且可以獨立撤銷的權杖,換走了密碼。

甚麼是授權範圍?

授權範圍是用戶批准的具體權限,例如讀取電郵或者寫入日曆。它們會出現在同意授權畫面上,並被編碼進存取權杖。資源伺服器負責執行這些範圍,所以一個只有讀取範圍的權杖無法寫入——最小權限是寫進協議裡的,而不是靠用戶端自律。

用 QueryChart(FlowJam)編輯這張圖解

把上面這張 OAuth 流程畫布開啟為你自己的圖表——把各方改名為你自己的服務,並註明你所請求的授權範圍。

用 QueryChart(FlowJam)編輯這張圖解

互動圖解的更多內容