OAuth2.0

1. 介紹

OAUTH協(xié)議為用戶資源的授權提供了一個安全的、開放而又簡易的標準迂卢。與以往的授權方式不同之處是OAUTH的授權不會使第三方觸及到用戶的帳號信息(如用戶名與密碼)楣富,即第三方無需使用用戶的用戶名與密碼就可以申請獲得該用戶資源的授權奕谭,因此OAUTH是安全的。oAuth是Open Authorization的簡寫尝蠕。

2. 理解

OAuth 就是一種授權機制。數(shù)據(jù)的所有者告訴系統(tǒng)载庭,同意授權第三方應用進入系統(tǒng)看彼,獲取這些數(shù)據(jù)。系統(tǒng)從而產(chǎn)生一個短期的進入令牌(token)囚聚,用來代替密碼靖榕,供第三方應用使用。

3. 角色
  • OAuth定義了四種角色:
    • 資源所有者
      能夠許可受保護資源訪問權限的實體靡挥。當資源所有者是個人時序矩,它作為最終用戶被提及。
    • 資源服務器
      托管受保護資源的服務器跋破,能夠接收和響應使用訪問令牌對受保護資源的請求簸淀。
    • 客戶端
      使用資源所有者的授權代表資源所有者發(fā)起對受保護資源的請求的應用程序瓶蝴。術語“客戶端”并非特指任何特定的的實現(xiàn)特點(例如:應用程序是否在服務器、臺式機或其他設備上執(zhí)行)租幕。
    • 授權服務器
      在成功驗證資源所有者且獲得授權后頒發(fā)訪問令牌給客戶端的服務器舷手。
      授權服務器和資源服務器之間的交互超出了本規(guī)范的范圍。授權服務器可以和資源服務器是同一臺服務器劲绪,也可以是分離的個體男窟。一個授權服務器可以頒發(fā)被多個資源服務器接受的訪問令牌。
4. 協(xié)議流程
+--------+                               +---------------+
 |        |--(A)- Authorization Request ->|   Resource    |
 |        |                               |     Owner     |
 |        |<-(B)-- Authorization Grant ---|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(C)-- Authorization Grant -->| Authorization |
 | Client |                               |     Server    |
 |        |<-(D)----- Access Token -------|               |
 |        |                               +---------------+
 |        |
 |        |                               +---------------+
 |        |--(E)----- Access Token ------>|    Resource   |
 |        |                               |     Server    |
 |        |<-(F)--- Protected Resource ---|               |
 +--------+                               +---------------+

上圖中所示的抽象OAuth 2.0流程描述了四個角色之間的交互贾富,包括以下步驟:

  • (A)客戶端向從資源所有者請求授權歉眷。授權請求可以直接向資源所有者發(fā)起(如圖所示),或者更可取的是通過作為中介的授權服務器間接發(fā)起颤枪。
  • (B)客戶端收到授權許可汗捡,這是一個代表資源所有者的授權的憑據(jù),使用本規(guī)范中定義的四種許可類型之一或 者使用擴展許可類型表示畏纲。授權許可類型取決于客戶端請求授權所使用的方式以及授權服務器支持的類型扇住。
  • (C)客戶端與授權服務器進行身份認證并出示授權許可請求訪問令牌。
  • (D)授權服務器驗證客戶端身份并驗證授權許可盗胀,若有效則頒發(fā)訪問令牌艘蹋。
  • (E)客戶端從資源服務器請求受保護資源并出示訪問令牌進行身份驗證。
  • (F)資源服務器驗證訪問令牌票灰,若有效則滿足該請求女阀。

客戶端用于從資源所有者獲得授權許可(步驟(A)和(B)所示)的更好方法是使用授權服務器作為中介。

5. 授權方式

OAuth 2.0 規(guī)定了四種獲得令牌的流程屑迂。你可以選擇最適合自己的那一種强品,向第三方應用頒發(fā)令牌。

  • 授權碼
  • 隱式授權
  • 資源所有者密碼憑據(jù)
  • 客戶端憑據(jù)
6. 詳細介紹四種授權方式
  • 授權碼(authorization code):指的是第三方應用先申請一個授權碼屈糊,然后再用該碼獲取令牌的榛。
    這種方式是最常用的流程,安全性也最高逻锐,它適用于那些有后端的 Web 應用夫晌。授權碼通過前端傳送,令牌則是儲存在后端昧诱,而且所有與資源服務器的通信都在后端完成晓淀。這樣的前后端分離,可以避免令牌泄漏盏档。

  • 第一步凶掰,A 網(wǎng)站提供一個鏈接,用戶點擊后就會跳轉到 B 網(wǎng)站,授權用戶數(shù)據(jù)給 A 網(wǎng)站使用懦窘。下面就是 A 網(wǎng)站跳轉 B 網(wǎng)站的一個示意鏈接前翎。

https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

上面 URL 中,response_type參數(shù)表示要求返回授權碼(code)畅涂,client_id參數(shù)讓 B 知道是誰在請求港华,redirect_uri參數(shù)是 B 接受或拒絕請求后的跳轉網(wǎng)址,scope參數(shù)表示要求的授權范圍(這里是只讀)午衰。

  • 第二步立宜,用戶跳轉后,B 網(wǎng)站會要求用戶登錄臊岸,然后詢問是否同意給予 A 網(wǎng)站授權橙数。用戶表示同意,這時 B 網(wǎng)站就會跳回redirect_uri參數(shù)指定的網(wǎng)址帅戒。跳轉時商模,會傳回一個授權碼,就像下面這樣蜘澜。
https://a.com/callback?code=AUTHORIZATION_CODE

上面 URL 中,code參數(shù)就是授權碼响疚。

  • 第三步鄙信,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

上面 URL 中,client_id參數(shù)和client_secret參數(shù)用來讓 B 確認 A 的身份(client_secret參數(shù)是保密的践盼,因此只能在后端發(fā)請求)鸦采,grant_type參數(shù)的值是AUTHORIZATION_CODE,表示采用的授權方式是授權碼咕幻,code參數(shù)是上一步拿到的授權碼渔伯,redirect_uri參數(shù)是令牌頒發(fā)后的回調網(wǎng)址。

  • 第四步肄程,B 網(wǎng)站收到請求以后锣吼,就會頒發(fā)令牌。具體做法是向redirect_uri指定的網(wǎng)址蓝厌,發(fā)送一段 JSON 數(shù)據(jù)玄叠。
{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{...}
}

上面 JSON 數(shù)據(jù)中,access_token字段就是令牌拓提,A 網(wǎng)站在后端拿到了读恃。

  • 隱式授權:有些 Web 應用是純前端應用,沒有后端。這時就不能用上面的方式了寺惫,必須將令牌儲存在前端疹吃。RFC 6749 就規(guī)定了第二種方式,允許直接向前端頒發(fā)令牌肌蜻。這種方式?jīng)]有授權碼這個中間步驟互墓,所以稱為(授權碼)"隱藏式"(implicit)。

  • 第一步蒋搜,A 網(wǎng)站提供一個鏈接篡撵,要求用戶跳轉到 B 網(wǎng)站,授權用戶數(shù)據(jù)給 A 網(wǎng)站使用豆挽。

https://b.com/oauth/authorize?
  response_type=token&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

上面 URL 中育谬,response_type參數(shù)為token,表示要求直接返回令牌帮哈。

  • 第二步膛檀,用戶跳轉到 B 網(wǎng)站,登錄后同意給予 A 網(wǎng)站授權娘侍。這時咖刃,B 網(wǎng)站就會跳回redirect_uri參數(shù)指定的跳轉網(wǎng)址,并且把令牌作為 URL 參數(shù)憾筏,傳給 A 網(wǎng)站嚎杨。
https://a.com/callback#token=ACCESS_TOKEN

上面 URL 中,token參數(shù)就是令牌氧腰,A 網(wǎng)站因此直接在前端拿到令牌枫浙。

  • 注意,令牌的位置是 URL 錨點(fragment)古拴,而不是查詢字符串(querystring)箩帚,這是因為 OAuth 2.0 允許跳轉網(wǎng)址是 HTTP 協(xié)議,因此存在"中間人攻擊"的風險黄痪,而瀏覽器跳轉時紧帕,錨點不會發(fā)到服務器,就減少了泄漏令牌的風險桅打。
    這種方式把令牌直接傳給前端焕参,是很不安全的。因此油额,只能用于一些安全要求不高的場景叠纷,并且令牌的有效期必須非常短,通常就是會話期間(session)有效潦嘶,瀏覽器關掉涩嚣,令牌就失效了崇众。

  • 資源所有者密碼憑據(jù):如果你高度信任某個應用,RFC 6749 也允許用戶把用戶名和密碼航厚,直接告訴該應用顷歌。該應用就使用你的密碼,申請令牌幔睬,這種方式稱為"密碼式"(password)眯漩。

  • 第一步,A 網(wǎng)站要求用戶提供 B 網(wǎng)站的用戶名和密碼麻顶。拿到以后赦抖,A 就直接向 B 請求令牌。

https://oauth.b.com/token?
  grant_type=password&
  username=USERNAME&
  password=PASSWORD&
  client_id=CLIENT_ID

上面 URL 中辅肾,grant_type參數(shù)是授權方式队萤,這里的password表示"密碼式",username和password是 B 的用戶名和密碼矫钓。

  • 第二步要尔,B 網(wǎng)站驗證身份通過后,直接給出令牌新娜。注意赵辕,這時不需要跳轉,而是把令牌放在 JSON 數(shù)據(jù)里面概龄,作為 HTTP 回應还惠,A 因此拿到令牌。
    這種方式需要用戶給出自己的用戶名/密碼旁钧,顯然風險很大,因此只適用于其他授權方式都無法采用的情況互拾,而且必須是用戶高度信任的應用歪今。

  • 憑證式:(client credentials),適用于沒有前端的命令行應用颜矿,即在命令行下請求令牌寄猩。

  • 第一步,A 應用在命令行向 B 發(fā)出請求骑疆。

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

上面 URL 中田篇,grant_type參數(shù)等于client_credentials表示采用憑證式,client_id和client_secret用來讓 B 確認 A 的身份箍铭。

  • 第二步泊柬,B 網(wǎng)站驗證通過以后,直接返回令牌诈火。
    這種方式給出的令牌兽赁,是針對第三方應用的,而不是針對用戶的,即有可能多個用戶共享同一個令牌刀崖。
7.令牌的使用

A 網(wǎng)站拿到令牌以后惊科,就可以向 B 網(wǎng)站的 API 請求數(shù)據(jù)了。

此時亮钦,每個發(fā)到 API 的請求馆截,都必須帶有令牌。具體做法是在請求的頭信息蜂莉,加上一個Authorization字段蜡娶,令牌就放在這個字段里面。

curl -H "Authorization: Bearer ACCESS_TOKEN" \
"https://api.b.com"

上面命令中巡语,ACCESS_TOKEN就是拿到的令牌翎蹈。

8. 更新令牌

令牌的有效期到了,如果讓用戶重新走一遍上面的流程男公,再申請一個新的令牌荤堪,很可能體驗不好,而且也沒有必要枢赔。OAuth 2.0 允許用戶自動更新令牌澄阳。

具體方法是,B 網(wǎng)站頒發(fā)令牌的時候踏拜,一次性頒發(fā)兩個令牌碎赢,一個用于獲取數(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

上面 URL 中枕赵,grant_type參數(shù)為refresh_token表示要求更新令牌,client_id參數(shù)和client_secret參數(shù)用于確認身份位隶,refresh_token參數(shù)就是用于更新令牌的令牌拷窜。

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

9. 實戰(zhàn)

如何通過 OAuth 獲取 API 數(shù)據(jù)篮昧。
很多網(wǎng)站登錄時,允許使用第三方網(wǎng)站的身份笋妥,這稱為"第三方登錄"懊昨。

image.png

GitHub 為例,寫一個最簡單的應用春宣,演示第三方登錄疚颊。

  • 第三方登錄的原理
    所謂第三方登錄狈孔,實質就是 OAuth 授權。用戶想要登錄 A 網(wǎng)站材义,A 網(wǎng)站讓用戶提供第三方網(wǎng)站的數(shù)據(jù)均抽,證明自己的身份。獲取第三方網(wǎng)站的身份數(shù)據(jù)其掂,就需要 OAuth 授權油挥。
    舉例來說,A 網(wǎng)站允許 GitHub 登錄款熬,背后就是下面的流程深寥。

    • A 網(wǎng)站讓用戶跳轉到 GitHub。
    • GitHub 要求用戶登錄贤牛,然后詢問"A 網(wǎng)站要求獲得 xx 權限惋鹅,你是否同意?"
    • 用戶同意殉簸,GitHub 就會重定向回 A 網(wǎng)站闰集,同時發(fā)回一個授權碼。
    • A 網(wǎng)站使用授權碼般卑,向 GitHub 請求令牌武鲁。
    • GitHub 返回令牌.
    • A 網(wǎng)站使用令牌,向 GitHub 請求用戶數(shù)據(jù)蝠检。
  • 應用登記

    • 進入GitHub官網(wǎng)沐鼠,登錄。
    • 打開 Setting > Developer setting > OAuth applications
    • 點擊 Register a new application
    • 填入基本的app信息
    • 提交表單以后叹谁,GitHub 應該會返回客戶端 ID(client ID)和客戶端密鑰(client secret)饲梭,這就是應用的身份識別碼。


      image.png

      image.png
  • 示例倉庫
    阮一峰示例倉庫

10. OAUTH2.0認證服務器搭建
11. 參考
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末焰檩,一起剝皮案震驚了整個濱河市憔涉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌锅尘,老刑警劉巖监氢,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件布蔗,死亡現(xiàn)場離奇詭異藤违,居然都是意外死亡,警方通過查閱死者的電腦和手機纵揍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門顿乒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人泽谨,你說我怎么就攤上這事璧榄√劁觯” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵骨杂,是天一觀的道長涂身。 經(jīng)常有香客問我,道長搓蚪,這世上最難降的妖魔是什么蛤售? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮妒潭,結果婚禮上悴能,老公的妹妹穿的比我還像新娘。我一直安慰自己雳灾,他們只是感情好漠酿,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著谎亩,像睡著了一般炒嘲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上团驱,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天摸吠,我揣著相機與錄音,去河邊找鬼嚎花。 笑死寸痢,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的紊选。 我是一名探鬼主播啼止,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兵罢!你這毒婦竟也來了献烦?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤卖词,失蹤者是張志新(化名)和其女友劉穎巩那,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體此蜈,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡即横,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了裆赵。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片东囚。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖战授,靈堂內(nèi)的尸體忽然破棺而出页藻,到底是詐尸還是另有隱情桨嫁,我是刑警寧澤,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布份帐,位于F島的核電站璃吧,受9級特大地震影響,放射性物質發(fā)生泄漏废境。R本人自食惡果不足惜肚逸,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望彬坏。 院中可真熱鬧朦促,春花似錦、人聲如沸栓始。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幻赚。三九已至禀忆,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間落恼,已是汗流浹背箩退。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留佳谦,地道東北人戴涝。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像钻蔑,于是被迫代替她去往敵國和親啥刻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 前言: 我也不知道這個前言怎么寫咪笑,反正我就是要加可帽。 我為什么要寫這篇文章?前些天調用一個普通的搜索...
    機智的老劉明同志閱讀 550評論 1 1
  • Introduction OAuth(Open Auth窗怒,開放授權 ) 就是一種授權機制映跟。數(shù)據(jù)的所有者告訴系統(tǒng),同...
    白色十字閱讀 279評論 0 0
  • OAuth是一個關于授權(authorization)的開放網(wǎng)絡標準扬虚,在全世界得到廣泛應用努隙,目前的版本是2.0...
    上善若水任意云閱讀 2,182評論 0 4
  • 原文地址:http://www.sanjinbest.com/blog/b6ec839d56c04ca387b95...
    木子小三金閱讀 8,543評論 0 37
  • 什么是三方授權? 第三方授權就是,委托第三方來對既定的用戶進行鑒定孔轴,鑒定成功之后剃法,下發(fā)信任憑證碎捺,信任憑證和用戶掛鉤...
    一只小哈閱讀 32,500評論 2 21