OAuth 2.0 的四種方式

上一篇文章介紹了 OAuth 2.0 是一種授權(quán)機制练慕,主要用來頒發(fā)令牌(token)惰匙。本文接著介紹頒發(fā)令牌的實務(wù)操作技掏。

image

下面我假定,你已經(jīng)理解了 OAuth 2.0 的含義和設(shè)計思想项鬼。

RFC 6749

OAuth 2.0 的標準是 RFC 6749 文件哑梳。該文件先解釋了 OAuth 是什么。

OAuth 引入了一個授權(quán)層绘盟,用來分離兩種不同的角色:客戶端和資源所有者鸠真。......資源所有者同意以后,資源服務(wù)器可以向客戶端頒發(fā)令牌龄毡》途恚客戶端通過令牌,去請求數(shù)據(jù)沦零。

這段話的意思就是祭隔,OAuth 的核心就是向第三方應(yīng)用頒發(fā)令牌。然后路操,RFC 6749 接著寫道:

(由于互聯(lián)網(wǎng)有多種場景疾渴,)本標準定義了獲得令牌的四種授權(quán)方式(authorization grant )。

也就是說屯仗,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)用粟按,是不會拿到令牌的。

第一種授權(quán)方式:授權(quán)碼

授權(quán)碼(authorization code)方式霹粥,指的是第三方應(yīng)用先申請一個授權(quán)碼灭将,然后再用該碼獲取令牌。

這種方式是最常用的流程后控,安全性也最高庙曙,它適用于那些有后端的 Web 應(yīng)用。授權(quán)碼通過前端傳送浩淘,令牌則是儲存在后端捌朴,而且所有與資源服務(wù)器的通信都在后端完成吴攒。這樣的前后端分離,可以避免令牌泄漏砂蔽。

第一步洼怔,A 網(wǎng)站提供一個鏈接,用戶點擊后就會跳轉(zhuǎn)到 B 網(wǎng)站左驾,授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用镣隶。下面就是 A 網(wǎng)站跳轉(zhuǎn) B 網(wǎng)站的一個示意鏈接。

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

第二步什荣,用戶跳轉(zhuǎn)后矾缓,B 網(wǎng)站會要求用戶登錄,然后詢問是否同意給予 A 網(wǎng)站授權(quán)稻爬。用戶表示同意嗜闻,這時 B 網(wǎng)站就會跳回redirect_uri參數(shù)指定的網(wǎng)址。跳轉(zhuǎn)時桅锄,會傳回一個授權(quán)碼琉雳,就像下面這樣。

https://a.com/callback?code=AUTHORIZATION_CODE

上面 URL 中友瘤,code參數(shù)就是授權(quán)碼翠肘。

image

第三步,A 網(wǎng)站拿到授權(quán)碼以后辫秧,就可以在后端束倍,向 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柿究,表示采用的授權(quán)方式是授權(quán)碼邮旷,code參數(shù)是上一步拿到的授權(quán)碼,redirect_uri參數(shù)是令牌頒發(fā)后的回調(diào)網(wǎng)址蝇摸。

image

第四步婶肩,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)站在后端拿到了。

image

第二種方式:隱藏式

有些 Web 應(yīng)用是純前端應(yīng)用,沒有后端辱揭。這時就不能用上面的方式了离唐,必須將令牌儲存在前端。RFC 6749 就規(guī)定了第二種方式问窃,允許直接向前端頒發(fā)令牌亥鬓。這種方式?jīng)]有授權(quán)碼這個中間步驟,所以稱為(授權(quán)碼)"隱藏式"(implicit)域庇。

第一步嵌戈,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 

上面 URL 中,response_type參數(shù)為token尉姨,表示要求直接返回令牌庵朝。

第二步,用戶跳轉(zhuǎn)到 B 網(wǎng)站又厉,登錄后同意給予 A 網(wǎng)站授權(quán)九府。這時,B 網(wǎng)站就會跳回redirect_uri參數(shù)指定的跳轉(zhuǎn)網(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 允許跳轉(zhuǎn)網(wǎng)址是 HTTP 協(xié)議腮猖,因此存在"中間人攻擊"的風(fēng)險,而瀏覽器跳轉(zhuǎn)時赞枕,錨點不會發(fā)到服務(wù)器澈缺,就減少了泄漏令牌的風(fēng)險。

image

這種方式把令牌直接傳給前端炕婶,是很不安全的姐赡。因此,只能用于一些安全要求不高的場景柠掂,并且令牌的有效期必須非常短项滑,通常就是會話期間(session)有效,瀏覽器關(guān)掉涯贞,令牌就失效了枪狂。

第三種方式:密碼式

如果你高度信任某個應(yīng)用危喉,RFC 6749 也允許用戶把用戶名和密碼,直接告訴該應(yīng)用州疾。該應(yīng)用就使用你的密碼辜限,申請令牌,這種方式稱為"密碼式"(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ù)是授權(quán)方式毒姨,這里的password表示"密碼式"哑蔫,usernamepassword是 B 的用戶名和密碼。

第二步手素,B 網(wǎng)站驗證身份通過后鸳址,直接給出令牌。注意泉懦,這時不需要跳轉(zhuǎn)稿黍,而是把令牌放在 JSON 數(shù)據(jù)里面,作為 HTTP 回應(yīng)崩哩,A 因此拿到令牌巡球。

這種方式需要用戶給出自己的用戶名/密碼,顯然風(fēng)險很大邓嘹,因此只適用于其他授權(quán)方式都無法采用的情況酣栈,而且必須是用戶高度信任的應(yīng)用。

第四種方式:憑證式

最后一種方式是憑證式(client credentials)汹押,適用于沒有前端的命令行應(yīng)用矿筝,即在命令行下請求令牌。

第一步棚贾,A 應(yīng)用在命令行向 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_idclient_secret用來讓 B 確認 A 的身份铸史。

第二步,B 網(wǎng)站驗證通過以后怯伊,直接返回令牌琳轿。

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

令牌的使用

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

此時中燥,每個發(fā)到 API 的請求,都必須帶有令牌塘偎。具體做法是在請求的頭信息疗涉,加上一個Authorization字段,令牌就放在這個字段里面吟秩。

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

上面命令中咱扣,ACCESS_TOKEN就是拿到的令牌。

更新令牌

令牌的有效期到了涵防,如果讓用戶重新走一遍上面的流程闹伪,再申請一個新的令牌,很可能體驗不好壮池,而且也沒有必要偏瓤。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ā)新的令牌。

寫到這里温峭,頒發(fā)令牌的四種方式就介紹完了猛铅。下一篇文章會編寫一個真實的 Demo,演示如何通過 OAuth 2.0 向 GitHub 的 API 申請令牌凤藏,然后再用令牌獲取數(shù)據(jù)奸忽。

(正文完)

來源:http://www.ruanyifeng.com/blog/2019/04/oauth-grant-types.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市揖庄,隨后出現(xiàn)的幾起案子栗菜,更是在濱河造成了極大的恐慌,老刑警劉巖蹄梢,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件疙筹,死亡現(xiàn)場離奇詭異,居然都是意外死亡禁炒,警方通過查閱死者的電腦和手機而咆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來幕袱,“玉大人暴备,你說我怎么就攤上這事“挤洌” “怎么了馍驯?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長玛痊。 經(jīng)常有香客問我汰瘫,道長,這世上最難降的妖魔是什么擂煞? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任混弥,我火速辦了婚禮,結(jié)果婚禮上对省,老公的妹妹穿的比我還像新娘蝗拿。我一直安慰自己,他們只是感情好蒿涎,可當(dāng)我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布哀托。 她就那樣靜靜地躺著,像睡著了一般劳秋。 火紅的嫁衣襯著肌膚如雪仓手。 梳的紋絲不亂的頭發(fā)上胖齐,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機與錄音嗽冒,去河邊找鬼呀伙。 笑死,一個胖子當(dāng)著我的面吹牛添坊,可吹牛的內(nèi)容都是我干的剿另。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼贬蛙,長吁一口氣:“原來是場噩夢啊……” “哼雨女!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起速客,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤戚篙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后溺职,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岔擂,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年浪耘,在試婚紗的時候發(fā)現(xiàn)自己被綠了乱灵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡七冲,死狀恐怖痛倚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情澜躺,我是刑警寧澤蝉稳,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站掘鄙,受9級特大地震影響耘戚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜操漠,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一收津、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浊伙,春花似錦撞秋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至哑子,卻和暖如春舅列,著一層夾襖步出監(jiān)牢的瞬間奉芦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工剧蹂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人烦却。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓宠叼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親其爵。 傳聞我的和親對象是個殘疾皇子冒冬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,916評論 2 344

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

  • 上一篇文章[http://www.ruanyifeng.com/blog/2019/04/oauth_design...
    筆名輝哥閱讀 3,072評論 0 55
  • 前言: 我也不知道這個前言怎么寫,反正我就是要加摩渺。 我為什么要寫這篇文章简烤?前些天調(diào)用一個普通的搜索...
    機智的老劉明同志閱讀 550評論 1 1
  • 1. 介紹 OAUTH協(xié)議為用戶資源的授權(quán)提供了一個安全的、開放而又簡易的標準摇幻。與以往的授權(quán)方式不同之處是OAUT...
    帶刀打天下閱讀 409評論 0 1
  • Introduction OAuth(Open Auth横侦,開放授權(quán) ) 就是一種授權(quán)機制宦焦。數(shù)據(jù)的所有者告訴系統(tǒng)刽虹,同...
    白色十字閱讀 279評論 0 0
  • 我們與惡之間的距離渔呵,就是與己心之間的距離吧 最近放假沒事看了《我們與惡的距離》豺撑,很久沒刷劇瘫证,沒想到這部劇這么好看俩块。...
    呱呱呱愛啊閱讀 305評論 0 0