妳知道第三方應用是怎麼存取妳的雲端資料嗎?
大家有聽過 OAuth 及 OpenID Connect (OIDC) 嗎?這次接到 L 社神秘任務,來跟大家說一說這兩個融入每個人日常生活中的認證授權技術。平時大家可能不太留意,其實現在常用(X)天天用(O)的各種各種線上服務,例如 Google、Facebook 及 LINE 提供的各種應用,都是基於這次要講的這兩個技術標準來建構他們的認證授權機制喔!
所以如果您好奇您平常在使用的網路應用是如何安全且便利的提供服務,這篇介紹值得您繼續看下去;又或著您正是要導入 OAuth 或 OIDC 的開發者,這次介紹也提供一個不錯的起點,讓您可以快速瞭解這兩個標準的核心概念。
這次介紹會分成兩篇系列文發布。這篇會先討論的議題是「第三方應用存取授權」,也就是會介紹 OAuth 2.0 的部份。ODIC 則稍後於下篇文章介紹。
接下來,一開始會先簡單介紹第三方應用,OAuth 2.0 協定以及他們兩者間的關係,讓非技術背景的讀者也能瞭解其概念。之後會逐步深入 OAuth 2.0 機制,包含流程、參與角色及訊息等,讓技術開發者可以為實作做好準備。最後以 LINE 提供的 OAuth 2.0 服務:LINE Login 為例,實際 demo 授權機制運作流程。
什麼是「第三方應用」
第三方應用是一個線上平台很常提供的功能,這個功能讓我們保存在不同服務的資訊可以互通有無,以方便使用。例如說許多新創團隊喜歡使用的 Slack 就可以與 Google Drive 做整合,讓用戶直接從 Slack 存取放在 Google Drive 上的檔案。在這個例子中,對 Google Drive 來說,Slack 就是一個第三方應用。
讓我們看一下設定讓 Slack 存取妳放在 Google Drive 的檔案的步驟:
在這個例子中有三個角色:1. Slack 2. Google 3. User 也就是妳。在設定過程中,Google 會再次跟您確認是不是真的要讓 Slack 存取檔案。在妳確認後,Slack 始能存取妳放在 Google Drive 的檔案。
你可以看到在整個設定過程中,最重要的就是怎麼授權給第三方應用,OAuth 2.0,就是實現了這整個授權流程。
OAuth 2.0:實現第三方應用存取授權
從前述流程中我們可以看到第三方應用存取授權會牽涉到不同廠商,因此需要有一個大家共同遵守的流程。OAuth 2.0 的主要目的就是建立一個標準化、廣泛被採用的授權流程,讓所有雲應用可以安全的方式互通分享權限和資料。
OAuth 2.0 主要有以下特點:
- 標準化:在沒有 OAuth 以前,一個服務若要提供第三方應用存取的功能必須個別客製化其機制。OAuth 2.0 建立了一個標準協定,例如前述例子的 Slack,就可以相同的 code base 介接 Google Drive、Dropbox、Onedrive 等服務。
- 廣泛採用:承上,一個標準要發揮效益,必須被廣為接受。OAuth 2.0 現在已經是各大主流雲服務業者所共同支持的標準,因此無論作為開發者或 end user,OAuth 都可以讓我們更便利的達成三方應用存取。
- 安全性:在沒有 OAuth 以前,用戶要授予第三方應用存取權,唯一方式可能是直接提供帳號密碼。這會造成許多安全性的問題,例如沒辦法限制第三方應用的存取資料範圍(以上述例子,Slack 除了可以看 Google drive 的檔案,也可能會跑去看 Gmail郵件、Google Photo 等。)OAuth 2.0 的代理授權(Delegated Authorization)機制,讓用戶可以個別授權第三方應用不同的權限,限制存取特定範圍的資料。
憑借上述優點及天時地利人和,目前市面上絕大多數雲服務在做第三方應用分享時,都是透過 OAuth 2.0 協定去完成授權囉!接下來就進一步去瞭解當我們平常點選那些授權畫面時,裡面的小精靈實際上是怎麼完成的!
OAuth 2.0 運作流程
以下將進入兔子洞,逐步介紹 OAuth 2.0 的流程、參與角色及訊息。
一、流程及授權憑證
我們將前面 Slack 和 Google Drive 的例子畫成這張流程圖,來說明 OAuth 2.0 的運作流程:
圖中有四個角色參與演出:1. User (You) 2. Slack 3. Google Account Service 4. Google Drive。流程目的是能夠在 Slack 存取用戶放在 Google Drive 的檔案。要達成這件事,Slack 要先取得「授權憑證。」
在 OAuth 2.0 中,有定義兩種授權憑證。第一種是 Authorization Code。在圖中的步驟 1~7,用戶向 Google Account 要到 Authorization Code,然後轉交給 Slack。第二種是 Access Token。在圖中的步驟 8~12,Slack 憑藉從用戶拿到的 Authorization Code,去跟 Google Account 換到 Access Token。Slack 換到 Access Token 以後,就可以存取 Google Drive,完成用戶要求的作業。
BTW,妳可能會疑惑,為什麼前面看到的 screenshot 才五張,這邊確有十多個步驟?這是因為有些步驟是由您的 browser 幫您完成的,例如步驟 1~4中,妳只會看到第一步的畫面和第四步的畫面,步驟二和三則是由 browser 自動跳轉。
二、角色定義
OAuth 2.0 中,將參與流程的角色分別定義為 Resource Owner、Client、Authorization Server 及 Resource Server。代換到圖中如下:
這張圖乍看之下蠻難理解的,這也是初學者碰到 OAuth 很常有障礙的地方。不過對照著上一張圖看,應該就比較好理解囉!
三、協定訊息
上圖還沒有詳細說明的是每個步驟傳遞的訊息,這邊進一步加入介紹:
挖開始變複雜惹~如果您不是開發者應該可以跳過不看;對開發者來說建議要掌握兩個部分,分別是步驟 2、6 及 步驟 8~9 ,這也是 OAuth 2.0 協定最核心的部分:取得 Authorization Code 以及換取 Access Token。以下陸續加以說明。
取得 Authorization Code 的 request 帶有以下參數:
- scope:前文有提到 OAuth 2.0 可以讓用戶個別授權第三方應用不同的權限,限制存取特定範圍的資料。這在實際上就是在取 Authorization Code的時候,以
scope
這個欄位來指定的!這在不同的服務會友不同的值,例如 profile、photo、contacts等。 - redirect_uri:在取得 Authorization Code 的過程中,用戶會依序連到 Client -> Authorization Server -> Client。這邊的切換是藉由 HTTP redirect 機制達成。
rediect_uri
就是指定完成授權以後,要重導向回的位置。 - client_id:在這個流程中,不是隨便的 Client 都可以取得授權。Client 在部署階段必須先與 Authorization Server 照會,Authorization Server 會為每個 Client 配給 ID。在 OAuth 2.0 的流程中,Authorization Server 憑藉 Client ID 識別 Client 的身分。
- response_type:在我們的例子中,固定為 authorization_code 。
- state:與避免資安攻擊及保存狀態有關,在此按表不提。
取得Authorization Code 的 Response 帶有以下資訊:
- code:既為取得的 Authorization Code。
- state:與避免資安攻擊及保存狀態有關,在此按表不提。
以 Authorization Code 換取 Access Token 的 Request 帶有以下參數:
- code:既為取得的 Authorization Code。
- client_id:與 Authorization Code Request 中意義相同。
- client_secret:顧名思義,是一個密碼的概念。
- grant_type:在我們的例子中,固定為
authorization_code
。
以 Authorization Code 換取 Access Token 的 Response 帶有以下資訊:
- access_token:既為取得的 Access Token。
這就是 OAuth 2.0 的全部了嗎?
前面介紹 OAuth 2.0 的流程、參與角色及訊息,但相信您還有很多疑問,實際上要實作 OAuth 也確實還有很多需要瞭解的部分。
但礙於篇幅及本次介紹需要考量非技術性的讀者,只能就此點到為止。相信這樣的資訊,應該可以滿足不是開發者的讀者;對於開發者,這樣的資訊也足夠讓您可以看得懂 OAuth 2.0 provider 或 library 提供的文件動手做了!選擇一間 OAuth 2.0 provider (例如下面要示範的 LINE Login ) 實際做一次以後,應該就會有一定程度的掌握了!
這部分最後留下一些沒講到的 keyword,供讀者進一步閱讀相關文章瞭解:
- OAuth 2.0 flows: 實際上 OAuth 2.0 依據適用情境,有不同的流程模式。本文介紹的是 “ Authorization Code Flow”,另外還有 Implicit、Resource Owner Password Credentials、Client Credentials 三種流程。
- Token 的 Validation、Expire/Refresh、Revocation
- 為什麼流程中要區分 Authorization Code 和 Access Token,不能直接給 Access Token 就好了嗎?這牽涉到 front channel / back channel 的差異,有興趣可以進一步瞭解。
DEMO: LINE Login
前面介紹完理論部份,現在讓我們弄髒手,實際來操作 OAuth 2.0 的機制看看吧!這邊使用 LINE Login 為例子,依據操作整個 OAuth 2.0 的流程,包含取得 Authorization Code 和 Access Token 等步驟。
合先敘明,LINE Login 官方手冊 已經寫得很完整了可以直接參考,這邊比較特別的是介紹 OAuth 2.0 Debugger 這個工具,比起實際寫 code 會對初心者友善很多。
一、註冊 LINE Login 帳戶
註冊步驟就點一點這邊就不多做說明拉,有需要可以直接參考 官方手冊。在以下示範的例子中,我的 LINE Login 應用名為 play-line-login。
註冊以後記得在 App Setting 分頁填寫 Callback URL,請填入我們待會要測試的工具位置:https://oauthdebugger.com/debug
二、取得 Authorization code
註冊完以後,就可以正式開始操作了。接下來 OAuth 2.0 Debugger 會扮演前面介紹 OAuth 2.0 時提到的 Client 的角色,LINE Login 則扮演 Authorization Server 。
首先我們登入 OAuth 2.0 Debugger,並填入相關資訊。其中 Authorize URL 要填入 LINE Login endpoint 位置: https://access.line.me/oauth2/v2.1/authorize。另外比較容易 confuse 的是 Client ID 是對應到 LINE Login Channel ID,不要找不到了~
填寫完成按送出就會開始流程。首先會被導到 LINE 登入畫面。這個步驟是要讓 LINE 先知道你是誰。
登入讓 LINE 知道你是誰以後,接下來 LINE 就會問你:「要不要讓 play-line-login 存取你的個人檔案阿~?」這邊要選【是】,這樣故事才講的下去。
許可以後,畫面就會跳轉回 OAuth 2.0 Debugger。OAuth 2.0 Debugger 顯示已經成功取得 Authorization code了 🎉 🎉 🎉,就是畫面中綠標的位置。
三、使用 Authorization Code換得 Access Token
在上一步取得 Authorization Code 以後事情還沒完,我們還要換到 Access Token,才能真正存取用戶資料。比較遺憾的是這個工具考量到到資安防呆,沒辦法幫我們做這一步驟。這邊我們使用常見但我覺得很難用的 Postman 來執行這步驟。
在這步驟中我們依序填入相關資料,比較要注意的是這次打的 endpoint 是用來取 token 的,不要搞錯了!code 則是填入上一步驟取得的 authorization code。最後是要記得填入剛剛沒用到的 client secret。
點擊發送以後,可以看到 200 OK 成功的取的了 Access Token,完成了整個 OAuth 2.0 的流程。棒棒!
小結
本文介紹「第三方應用存取授權」背後的核心技術: OAuth 2.0
- OAuth 2.0 是目前最廣泛被採用的第三方應用存取授權機制標準。
- OAuth 2.0 協定流程主要由 Resource Owner、Client、Authorization Server 及 Resource Server 四種角色參與。在本文介紹的模式中,主要有兩個步驟:1. 取得 Authorization Code 2. 換取 Access Token。
對於非技術但充滿好奇心讀者,希望您會覺得這是一篇還算有趣的科普文章,現在,您知道當你連結您的Google帳號到到其他第三方應用時,背後發生了什麼事了吧! 👻👻👻
對於和我一樣是開發者的讀者,希望這篇文章介紹的一些概念及實測經驗,會對您開發相關應用有幫助,Project 不 delay 上線沒bug 🤘🏽🤘🏽🤘🏽。
最後無論您是哪種類型的讀者,如果您喜歡這篇文章,歡迎按讚分享,並且期待下一集:Open ID Connect 介紹!