【全棧修煉】OAuth2 修煉寶典

一、OAuth 概念

開放授權(quán)(OAuth)是一個開放標(biāo)準(zhǔn),允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲的私密的資源(如照片,視頻,聯(lián)系人列表),而無需將用戶名和密碼提供給第三方應(yīng)用。 —— 維基百科

嚴(yán)格來說,OAuth2 不是一個標(biāo)準(zhǔn)協(xié)議,而是一個安全的授權(quán)框架。其詳細(xì)描述系統(tǒng)中不同角色,用戶,服務(wù)前端應(yīng)用(如 API )以及客戶端(如網(wǎng)站或APP)之間如何實(shí)現(xiàn)相互認(rèn)證。

當(dāng)前 OAuth 協(xié)議版本是 OAuth2.0,需要注意的是,OAuth2.0 并不向下兼容 OAuth1.0。

在生活中,比較常見的 OAuth2 的使用場景是授權(quán)登錄,并且也廣泛應(yīng)用于 web、桌面應(yīng)用和移動 APP 的第三方服務(wù)提供授權(quán)登錄驗(yàn)證機(jī)制,以實(shí)現(xiàn)不同應(yīng)用直接數(shù)據(jù)訪問的權(quán)限。

二、OAuth2 重點(diǎn)名詞介紹

在 OAuth2 標(biāo)準(zhǔn)中定義了以下四種角色:

  • 資源擁有者 (Resource Owner):

代表授權(quán)客戶端訪問本身資源信息的用戶(User);

  • 客戶端 (Client):

代表意圖訪問受限資源的第三方應(yīng)用。

  • 資源服務(wù)器 (Resource Server):

代表托管了受保護(hù)的用戶賬號信息的服務(wù)器,它與認(rèn)證服務(wù)器,可以是同一臺服務(wù)器,也可以是不同的服務(wù)器;

  • 授權(quán)服務(wù)器 (Authorization Server):

代表驗(yàn)證用戶身份然后為客戶端派發(fā)資源訪問令牌的服務(wù)器,即服務(wù)提供商專門用來處理認(rèn)證的服務(wù)器;

三、OAuth2 運(yùn)行流程

1. 流程分析

20191028-OAuth2-01.png

(配圖來自阮一峰大佬

大致流程概括就是:

  • (A)Authrization Request

用戶打開客戶端以后,客戶端要求用戶給予授權(quán)。

  • (B)Authorization Grant(Get)

用戶同意給予客戶端授權(quán)。

  • (C)Authorization Grant(Post)

客戶端向授權(quán)服務(wù)器發(fā)送它自己的客戶端身份標(biāo)識和上一步中獲得的授權(quán)(authorization grant),向認(rèn)證服務(wù)器申請令牌。

  • (D)Access Token(Get)

認(rèn)證服務(wù)器對客戶端進(jìn)行認(rèn)證以后,確認(rèn)無誤,同意發(fā)放令牌(access token),授權(quán)階段至此全部結(jié)束。

  • (E)Access Token(Post && Validate)

客戶端使用令牌,向資源服務(wù)器申請獲取資源。

  • (F)Protected Resource(Get)

資源服務(wù)器確認(rèn)令牌無誤,同意向客戶端開放資源。

理解完上面整個流程以后,我們再看看下面這張圖,能更加清晰理解 OAuth2 的整個運(yùn)行流程:

20191028-OAuth2-02.png

(配圖來自公眾號前端修仙之路

從整個流程可以看出,在 B 步驟最為關(guān)鍵,即需要獲取到用戶對客戶端的授權(quán)(如我們在微信掃碼登錄時,點(diǎn)擊“確定”按鈕的步驟)。

有了這個授權(quán)以后,客戶端才能拿到令牌,進(jìn)而憑令牌向資源服務(wù)器獲取資源。

2. 案例:微信登錄

另外,微信登錄的實(shí)現(xiàn)流程也類似:

20191028-OAuth2-03.png

(配圖來自微信官方文檔

其整體流程為:

  1. 第三方發(fā)起微信授權(quán)登錄請求,微信用戶允許授權(quán)第三方應(yīng)用后,微信會拉起應(yīng)用或重定向到第三方網(wǎng)站,并且?guī)鲜跈?quán)臨時票據(jù) code 參數(shù);

  2. 通過 code 參數(shù)加上 AppIDAppSecret 等,通過 API 換取 access_token

  3. 通過 access_token 進(jìn)行接口調(diào)用,獲取用戶基本數(shù)據(jù)資源或幫助用戶實(shí)現(xiàn)基本操作

3. OAuth2 優(yōu)缺點(diǎn)

  • 優(yōu)點(diǎn):

適合快速開發(fā)實(shí)施,代碼量少,API需要被不同APP使用,且每個APP使用方式也不同的情況。

  • 缺點(diǎn):

學(xué)習(xí)和理解的成本比較大,并且 OAuth2 不是一個嚴(yán)格的標(biāo)準(zhǔn)協(xié)議,在實(shí)施過程中更容易出錯。

四、OAuth2 四種授權(quán)模式

通過前面描述,可以知道OAuth 的核心就是向第三方應(yīng)用頒發(fā)令牌。

OAuth 2.0 規(guī)定了四種獲得令牌的流程。你可以選擇最適合自己的那一種,向第三方應(yīng)用頒發(fā)令牌。即以下四種授權(quán)方式:

  • 授權(quán)碼(authorization-code)
  • 隱藏式(implicit)
  • 密碼式(password)
  • 客戶端憑證(client credentials)

注意:

不管哪一種授權(quán)方式,第三方應(yīng)用申請令牌之前,都必須先到系統(tǒng)備案,說明自己的身份,然后會拿到兩個身份識別碼:客戶端 ID(client ID)客戶端密鑰(client secret)

這是為了防止令牌被濫用,沒有備案過的第三方應(yīng)用,是不會拿到令牌的。

1. 授權(quán)碼(authorization code)

第三方應(yīng)用先申請一個授權(quán)碼,然后再用該碼獲取令牌。

適用于有后端的 Web 應(yīng)用,授權(quán)碼通過前端傳送,令牌則是儲存在后端,而且所有與資源服務(wù)器的通信都在后端完成。這樣的前后端分離,可以避免令牌泄漏。

這種方式也是最常用的流程,安全性最高。

整體流程

20191028-OAuth2-04.png

(配圖來自阮一峰大佬

步驟分析

  1. 用戶從 A 網(wǎng)站跳轉(zhuǎn)到 B 網(wǎng)站,請求用戶確認(rèn)授權(quán),以獲取授權(quán)碼,其發(fā)送鏈接示意如下:
https://b.com/oauth/authorize?
       response_type=code&
       client_id=CLIENT_ID&
       redirect_uri=CALLBACK_URL&
       scope=read

其中:

response_type 參數(shù)表示要求返回授權(quán)碼(code);

client_id 參數(shù)讓 B 知道是誰在請求;

redirect_uri 參數(shù)是 B 接受或拒絕請求后的跳轉(zhuǎn)網(wǎng)址;

scope 參數(shù)表示要求的授權(quán)范圍(這里是只讀);

  1. 在 B 網(wǎng)站中,當(dāng)用戶同意授權(quán) A 網(wǎng)站,則 B 網(wǎng)站會攜帶授權(quán)碼,重定向到 redirect_uri 參數(shù)指定的網(wǎng)址,就像下面這樣:
https://a.com/callback?code=AUTHORIZATION_CODE
  1. A 網(wǎng)站獲取授權(quán)碼以后,在 A 網(wǎng)站后端中向 B 網(wǎng)站請求令牌:
https://b.com/oauth/token?
       client_id=CLIENT_ID&
       client_secret=CLIENT_SECRET&
       grant_type=authorization_code&
       code=AUTHORIZATION_CODE&
       redirect_uri=CALLBACK_URL

client_id 參數(shù)和 client_secret 參數(shù)用來讓 B 確認(rèn) A 的身份( client_secret 參數(shù)是保密的,因此只能在后端發(fā)請求);

grant_type 參數(shù)的值是 AUTHORIZATION_CODE ,表示采用的授權(quán)方式是授權(quán)碼;

code 參數(shù)是上一步拿到的授權(quán)碼;

redirect_uri 參數(shù)是令牌頒發(fā)后的回調(diào)網(wǎng)址;

  1. B 網(wǎng)站接受請求并驗(yàn)證身份,身份驗(yàn)證通過后,會發(fā)放令牌。向redirect_uri 指定的網(wǎng)址,發(fā)送包含令牌 access_token 字段的JSON數(shù)據(jù),流程完畢。

2. 隱藏式(implicit)

隱藏授權(quán)碼步驟,直接向前端發(fā)放令牌,也稱授權(quán)碼隱藏式。

整體流程

20191028-OAuth2-05.png

(配圖來自阮一峰大佬

步驟分析

  1. 用戶從 A 網(wǎng)站跳轉(zhuǎn)到 B 網(wǎng)站,要求授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用。
https://b.com/oauth/authorize?
  response_type=token&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

response_type 參數(shù)為 token,表示要求直接返回令牌。

  1. 用戶在 B 網(wǎng)站同意授權(quán)給 A 網(wǎng)站。

當(dāng)用戶同意授權(quán)后,會跳轉(zhuǎn)到 redirect_uri 參數(shù)指定的重定向地址,并將令牌作為 URL 參數(shù)傳遞給 A 網(wǎng)站。

https://a.com/callback#token=ACCESS_TOKEN

token 參數(shù)就是令牌,A 網(wǎng)站因此直接在前端拿到令牌。

注意:

這里的令牌位置是 URL 錨點(diǎn)(即 # 號),而不是查詢字符串,這是因?yàn)殄^點(diǎn)不會發(fā)到服務(wù)器,避免泄露令牌的風(fēng)險。

適用場景:

由于直接傳遞令牌不安全,因此常常適用在對安全要求不高的場景,并且令牌有效期非常短,例如會話期間(session)有效,關(guān)閉瀏覽器便失效。

3. 密碼式(password)

即:對于信任的應(yīng)用,可以攜帶約定的用戶名和密碼進(jìn)行令牌申請

流程分析

20191028-OAuth2-07.png
  1. A 網(wǎng)站使用 B 網(wǎng)站提供的用戶名和密碼,向 B 網(wǎng)站發(fā)起令牌請求。
https://oauth.b.com/token?
  grant_type=password&
  username=USERNAME&
  password=PASSWORD&
  client_id=CLIENT_ID

grant_type 參數(shù)是授權(quán)方式,這里的 password 表示"密碼式";
usernamepassword 是 B 的用戶名和密碼。

  1. B 網(wǎng)站驗(yàn)證身份后直接將令牌存在 JSON 數(shù)據(jù)中,作為 HTTP 相應(yīng)返回令牌給 A 網(wǎng)站。

適用場景:

風(fēng)險較大,一般適用在對應(yīng)用高度信任的情況。

4. 客戶端憑證(client credentials)

即:給出憑證讓對方確認(rèn)并提供令牌。

流程分析

  1. A 應(yīng)用在命令行向 B 發(fā)出請求。
https://oauth.b.com/token?
  grant_type=client_credentials&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET

grant_type 參數(shù)等于 client_credentials 表示采用憑證式;
client_idclient_secret 用來讓 B 確認(rèn) A 的身份。

  1. B 網(wǎng)站驗(yàn)證身份后返回令牌。

這種方式給出的令牌,是針對第三方應(yīng)用的,而不是針對用戶的,即有可能多個用戶共享同一個令牌。

適用場景:

通過命令行請求令牌。

流程分析

20191028-OAuth2-06.png

五、使用令牌

當(dāng)網(wǎng)站獲取到令牌以后,接下來每個 API 請求都需要帶上令牌,其做法是在請求的頭信息中,將令牌添加 Authorization 字段中。

六、更新令牌

當(dāng)令牌有效期到了,OAuth2 允許用戶自動更新令牌,而不用讓用戶重新授權(quán)獲取新令牌。

具體流程:

在 B 網(wǎng)站發(fā)放令牌時,一次性發(fā)放 2 個令牌,一個用于獲取數(shù)據(jù),一個用于獲取新的令牌(refresh token 字段)。令牌到期后,用戶使用 refresh token 發(fā)送請求去更新令牌:

https://b.com/oauth/token?
  grant_type=refresh_token&
  client_id=CLIENT_ID&
  client_secret=CLIENT_SECRET&
  refresh_token=REFRESH_TOKEN

grant_type 參數(shù)為 refresh_token 表示要求更新令牌;
client_id 參數(shù)和 client_secret 參數(shù)用于確認(rèn)身份;
refresh_token 參數(shù)就是用于更新令牌的令牌。

B 網(wǎng)站驗(yàn)證通過以后,就會頒發(fā)新的令牌。

參考文章

  1. 部門內(nèi)部培訓(xùn)資料
  2. 《OAuth 2 深入介紹》
  3. 《阮一峰 理解OAuth 2.0》
  4. 《阮一峰 OAuth 2.0 的四種方式》

關(guān)于我

本文首發(fā)在 pingan8787個人博客,如需轉(zhuǎn)載請聯(lián)系本人。

Author 王平安
E-mail pingan8787@qq.com
博 客 www.pingan8787.com
微 信 pingan8787
每日文章推薦 https://github.com/pingan8787/Leo_Reading/issues
ES小冊 js.pingan8787.com

微信公眾號

bg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • OAuth2.0 是關(guān)于授權(quán)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn),它允許用戶已第三方應(yīng)用獲取該用戶在某一網(wǎng)站的私密資源,而無需提供用戶名...
    baiyi閱讀 10,695評論 4 25
  • 原文地址:http://www.sanjinbest.com/blog/b6ec839d56c04ca387b95...
    木子小三金閱讀 8,744評論 0 37
  • Spring OAuth2.0 提供者實(shí)現(xiàn)原理: Spring OAuth2.0提供者實(shí)際上分為: 授權(quán)服務(wù) Au...
    EnchIGo閱讀 1,293評論 0 5
  • 1. 介紹 OAUTH協(xié)議為用戶資源的授權(quán)提供了一個安全的、開放而又簡易的標(biāo)準(zhǔn)。與以往的授權(quán)方式不同之處是OAUT...
    帶刀打天下閱讀 471評論 0 1
  • 什么是三方授權(quán)? 第三方授權(quán)就是,委托第三方來對既定的用戶進(jìn)行鑒定,鑒定成功之后,下發(fā)信任憑證,信任憑證和用戶掛鉤...
    一只小哈閱讀 33,063評論 2 21

友情鏈接更多精彩內(nèi)容