簡述 OAuth 2.0 的運作流程
本文將以用戶使用 github 登錄網站留言為例,簡述 OAuth 2.0 的運作流程。
假如我有一個網站,你是我網站上的訪客,看了文章想留言表示「朕已閱」,留言時發現有這個網站的帳號才能夠留言,此時給了你兩個選擇:一個是在我的網站上注冊擁有一個新賬戶,然后用注冊的用戶名來留言;一個是使用 github 帳號登錄,使用你的 github 用戶名來留言。前者你覺得過于繁瑣,于是慣性地點擊了 github 登錄按鈕,此時 OAuth 認證流程就開始了。
需要明確的是,即使用戶剛登錄過 github,我的網站也不可能向 github 發一個什么請求便能夠拿到訪客信息,這顯然是不安全的。就算用戶允許你獲取他在 github 上的信息,github 為了保障用戶信息安全,也不會讓你隨意獲取。所以操作之前,我的網站與 github 之間需要要有一個協商。
1. 網站和 Github 之間的協商
Github 會對用戶的權限做分類,比如讀取倉庫信息的權限、寫入倉庫的權限、讀取用戶信息的權限、修改用戶信息的權限等等。如果我想獲取用戶的信息,Github 會要求我,先在它的平臺上注冊一個應用,在申請的時候標明需要獲取用戶信息的哪些權限,用多少就申請多少,并且在申請的時候填寫你的網站域名,Github 只允許在這個域名中獲取用戶信息。
此時我的網站已經和 Github 之間達成了共識,Github 也給我發了兩張門票,一張門票叫做 Client Id,另一張門票叫做 Client Secret。
2. 用戶和 Github 之間的協商
用戶進入我的網站,點擊 github 登錄按鈕的時候,我的網站會把上面拿到的 Client Id 交給用戶,讓他進入到 Github 的授權頁面,Github 看到了用戶手中的門票,就知道這是我的網站讓他過來的,于是它就把我的網站想要獲取的權限擺出來,并詢問用戶是否允許我獲取這些權限。
// 用戶登錄 github,協商 GET https://github.com/login/oauth/authorize // 協商憑證 params = { client_id: "xxxx", redirect_uri: "http://my-website.com" }
如果用戶覺得我的網站要的權限太多,或者壓根就不想我知道他這些信息,選擇了拒絕的話,整個 OAuth 2.0 的認證就結束了,認證也以失敗告終。如果用戶覺得 OK,在授權頁面點擊了確認授權后,頁面會跳轉到我預先設定的 redirect_uri 并附帶一個蓋了章的門票 code。
// 協商成功后帶著蓋了章的 code Location: http://my-website.com?code=xxx
這個時候,用戶和 Github 之間的協商就已經完成,Github 也會在自己的系統中記錄這次協商,表示該用戶已經允許在我的網站訪問上直接操作和使用他的部分資源。
3. 告訴 Github 我的網站要來拜訪了
第二步中,我們已經拿到了蓋過章的門票 code,但這個 code 只能表明,用戶允許我的網站從 github 上獲取該用戶的數據,如果我直接拿這個 code 去 github 訪問數據一定會被拒絕,因為任何人都可以持有 code,github 并不知道 code 持有方就是我本人。
還記得之前申請應用的時候 github 給我的兩張門票么,Client Id 在上一步中已經用過了,接下來輪到另一張門票 Client Secret。
// 網站和 github 之間的協商 POST https://github.com/login/oauth/access_token // 協商憑證包括 github 給用戶蓋的章和 github 發給我的門票 params = { code: "xxx", client_id: "xxx", client_secret: "xxx", redirect_uri: "http://my-website.com" }
拿著用戶蓋過章的 code 和能夠標識個人身份的 client_id、client_secret 去拜訪 github,拿到最后的綠卡 access_token。
// 拿到最后的綠卡 response = { access_token: "e72e16c7e42f292c6912e7710c838347ae178b4a" scope: "user,gist" token_type: "bearer", refresh_token: "xxxx" }
4. 用戶開始使用 github 帳號在我的頁面上留言
// 訪問用戶數據 GET https://api.github.com/user?access_token=e72e16c7e42f292c6912e7710c838347ae178b4a
上一步 github 已經把最后的綠卡 access_token 給我了,通過 github 提供的 API 加綠卡就能夠訪問用戶的信息了,能獲取用戶的哪些權限在 response 中也給了明確的說明,scope 為 user 和 gist,也就是只能獲取 user 組和 gist 組兩個小組的權限,user 組中就包含了用戶的名字和郵箱等信息了。
// 告訴我用戶的名字和郵箱 response = { username: "barretlee", email: "barret.china@gmail.com" }
整個 OAuth2 流程在這里也基本完成了,文章中的表述很粗糙,比如 access_token 這個綠卡是有過期時間的,如果過期了需要使用 refresh_token 重新簽證。重點是讓讀者理解整個流程,細節部分可以閱讀 RFC6749 文檔 。
希望對你理解 OAuth 2.0 有幫助。(本文完)
來自: http://www.barretlee.com/blog/2016/01/10/oauth2-introduce/