OAuth 2.0 的一個(gè)簡單解釋,一看就懂

【轉(zhuǎn)載】原文鏈接

OAuth 2.0

OAuth 2.0 是目前最流行的授權(quán)機(jī)制,用來授權(quán)第三方應(yīng)用珠插,獲取用戶數(shù)據(jù)秧骑。

這個(gè)標(biāo)準(zhǔn)比較抽象,使用了很多術(shù)語户誓,初學(xué)者不容易理解。其實(shí)說起來并不復(fù)雜幕侠,下面我就通過一個(gè)簡單的類比帝美,幫助大家輕松理解,OAuth 2.0 到底是什么晤硕。

一悼潭、快遞員問題

我住在一個(gè)大型的居民小區(qū)庇忌,小區(qū)有門禁系統(tǒng),進(jìn)入的時(shí)候需要輸入密碼女责。

我經(jīng)常網(wǎng)購和外賣漆枚,每天都有快遞員來送貨。我必須找到一個(gè)辦法抵知,讓快遞員通過門禁系統(tǒng)墙基,進(jìn)入小區(qū)。

如果我把自己的密碼刷喜,告訴快遞員残制,他就擁有了與我同樣的權(quán)限,這樣好像不太合適掖疮。萬一我想取消他進(jìn)入小區(qū)的權(quán)力初茶,也很麻煩,我自己的密碼也得跟著改了浊闪,還得通知其他的快遞員恼布。

有沒有一種辦法,讓快遞員能夠自由進(jìn)入小區(qū)搁宾,又不必知道小區(qū)居民的密碼折汞,而且他的唯一權(quán)限就是送貨,其他需要密碼的場合盖腿,他都沒有權(quán)限爽待?

二、授權(quán)機(jī)制的設(shè)計(jì)

于是翩腐,我設(shè)計(jì)了一套授權(quán)機(jī)制鸟款。

第一步,門禁系統(tǒng)的密碼輸入器下面茂卦,增加一個(gè)按鈕何什,叫做"獲取授權(quán)"〉攘快遞員需要首先按這個(gè)按鈕处渣,去申請(qǐng)授權(quán)。

第二步而咆,他按下按鈕以后霍比,屋主(也就是我)的手機(jī)就會(huì)跳出對(duì)話框:有人正在要求授權(quán)幕袱。系統(tǒng)還會(huì)顯示該快遞員的姓名暴备、工號(hào)和所屬的快遞公司。

我確認(rèn)請(qǐng)求屬實(shí)们豌,就點(diǎn)擊按鈕涯捻,告訴門禁系統(tǒng)浅妆,我同意給予他進(jìn)入小區(qū)的授權(quán)。

第三步障癌,門禁系統(tǒng)得到我的確認(rèn)以后凌外,向快遞員顯示一個(gè)進(jìn)入小區(qū)的令牌(access token)。令牌就是類似密碼的一串?dāng)?shù)字涛浙,只在短期內(nèi)(比如七天)有效康辑。

第四步,快遞員向門禁系統(tǒng)輸入令牌轿亮,進(jìn)入小區(qū)疮薇。

有人可能會(huì)問,為什么不是遠(yuǎn)程為快遞員開門我注,而要為他單獨(dú)生成一個(gè)令牌按咒?這是因?yàn)榭爝f員可能每天都會(huì)來送貨,第二天他還可以復(fù)用這個(gè)令牌但骨。另外励七,有的小區(qū)有多重門禁,快遞員可以使用同一個(gè)令牌通過它們奔缠。

三掠抬、互聯(lián)網(wǎng)場景

我們把上面的例子搬到互聯(lián)網(wǎng),就是 OAuth 的設(shè)計(jì)了添坊。

首先剿另,居民小區(qū)就是儲(chǔ)存用戶數(shù)據(jù)的網(wǎng)絡(luò)服務(wù)。比如贬蛙,微信儲(chǔ)存了我的好友信息雨女,獲取這些信息,就必須經(jīng)過微信的"門禁系統(tǒng)"阳准。

其次氛堕,快遞員(或者說快遞公司)就是第三方應(yīng)用,想要穿過門禁系統(tǒng)野蝇,進(jìn)入小區(qū)讼稚。

最后,我就是用戶本人绕沈,同意授權(quán)第三方應(yīng)用進(jìn)入小區(qū)锐想,獲取我的數(shù)據(jù)。

簡單說乍狐,OAuth 就是一種授權(quán)機(jī)制赠摇。數(shù)據(jù)的所有者告訴系統(tǒng),同意授權(quán)第三方應(yīng)用進(jìn)入系統(tǒng),獲取這些數(shù)據(jù)藕帜。系統(tǒng)從而產(chǎn)生一個(gè)短期的進(jìn)入令牌(token)烫罩,用來代替密碼,供第三方應(yīng)用使用洽故。

四贝攒、令牌與密碼

令牌(token)與密碼(password)的作用是一樣的,都可以進(jìn)入系統(tǒng)时甚,但是有三點(diǎn)差異隘弊。

  1. 令牌是短期的,到期會(huì)自動(dòng)失效荒适,用戶自己無法修改长捧。密碼一般長期有效,用戶不修改吻贿,就不會(huì)發(fā)生變化串结。

  2. 令牌可以被數(shù)據(jù)所有者撤銷,會(huì)立即失效舅列。以上例而言肌割,屋主可以隨時(shí)取消快遞員的令牌。密碼一般不允許被他人撤銷帐要。

  3. 令牌有權(quán)限范圍(scope)把敞,比如只能進(jìn)小區(qū)的二號(hào)門。對(duì)于網(wǎng)絡(luò)服務(wù)來說榨惠,只讀令牌就比讀寫令牌更安全奋早。密碼一般是完整權(quán)限。

上面這些設(shè)計(jì)赠橙,保證了令牌既可以讓第三方應(yīng)用獲得權(quán)限耽装,同時(shí)又隨時(shí)可控,不會(huì)危及系統(tǒng)安全期揪。這就是 OAuth 2.0 的優(yōu)點(diǎn)掉奄。

注意,只要知道了令牌凤薛,就能進(jìn)入系統(tǒng)姓建。系統(tǒng)一般不會(huì)再次確認(rèn)身份,所以令牌必須保密缤苫,泄漏令牌與泄漏密碼的后果是一樣的速兔。 這也是為什么令牌的有效期,一般都設(shè)置得很短的原因活玲。

OAuth 2.0 對(duì)于如何頒發(fā)令牌的細(xì)節(jié)涣狗,規(guī)定得非常詳細(xì)帜矾。具體來說,一共分成四種授權(quán)類型(authorization grant)屑柔,即四種頒發(fā)令牌的方式,適用于不同的互聯(lián)網(wǎng)場景珍剑。

四種方式

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

授權(quán)碼(authorization code)方式掸宛,指的是第三方應(yīng)用先申請(qǐng)一個(gè)授權(quán)碼,然后再用該碼獲取令牌招拙。

這種方式是最常用的流程唧瘾,安全性也最高,它適用于那些有后端的 Web 應(yīng)用别凤。授權(quán)碼通過前端傳送饰序,令牌則是儲(chǔ)存在后端,而且所有與資源服務(wù)器的通信都在后端完成规哪。這樣的前后端分離求豫,可以避免令牌泄漏。

第一步诉稍,A 網(wǎng)站提供一個(gè)鏈接蝠嘉,用戶點(diǎn)擊后就會(huì)跳轉(zhuǎn)到 B 網(wǎng)站,授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用杯巨。下面就是 A 網(wǎng)站跳轉(zhuǎn) B 網(wǎng)站的一個(gè)示意鏈接蚤告。

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

上面 URL 中,response_type參數(shù)表示要求返回授權(quán)碼(code)服爷,client_id參數(shù)讓 B 知道是誰在請(qǐng)求杜恰,redirect_uri參數(shù)是 B 接受或拒絕請(qǐng)求后的跳轉(zhuǎn)網(wǎng)址,scope參數(shù)表示要求的授權(quán)范圍(這里是只讀)仍源。

請(qǐng)求授權(quán)碼

第二步心褐,用戶跳轉(zhuǎn)后,B 網(wǎng)站會(huì)要求用戶登錄笼踩,然后詢問是否同意給予 A 網(wǎng)站授權(quán)檬寂。用戶表示同意,這時(shí) B 網(wǎng)站就會(huì)跳回redirect_uri參數(shù)指定的網(wǎng)址戳表。跳轉(zhuǎn)時(shí)桶至,會(huì)傳回一個(gè)授權(quán)碼,就像下面這樣匾旭。

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

上面 URL 中镣屹,code參數(shù)就是授權(quán)碼。

返回授權(quán)碼

第三步价涝,A 網(wǎng)站拿到授權(quán)碼以后女蜈,就可以在后端,向 B 網(wǎng)站請(qǐ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 確認(rèn) A 的身份(client_secret參數(shù)是保密的逸寓,因此只能在后端發(fā)請(qǐng)求)狐援,grant_type參數(shù)的值是AUTHORIZATION_CODE芽腾,表示采用的授權(quán)方式是授權(quán)碼,code參數(shù)是上一步拿到的授權(quán)碼礼烈,redirect_uri參數(shù)是令牌頒發(fā)后的回調(diào)網(wǎng)址簇宽。

請(qǐng)求令牌

第四步勋篓,B 網(wǎng)站收到請(qǐng)求以后,就會(huì)頒發(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 應(yīng)用是純前端應(yīng)用遭垛,沒有后端盐股。這時(shí)就不能用上面的方式了,必須將令牌儲(chǔ)存在前端耻卡。RFC 6749 就規(guī)定了第二種方式疯汁,允許直接向前端頒發(fā)令牌。這種方式?jīng)]有授權(quán)碼這個(gè)中間步驟卵酪,所以稱為(授權(quán)碼)"隱藏式"(implicit)幌蚊。

第一步,A 網(wǎng)站提供一個(gè)鏈接溃卡,要求用戶跳轉(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)。這時(shí)峻村,B 網(wǎng)站就會(huì)跳回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 錨點(diǎn)(fragment)锚扎,而不是查詢字符串(querystring),這是因?yàn)?OAuth 2.0 允許跳轉(zhuǎn)網(wǎng)址是 HTTP 協(xié)議馁启,因此存在"中間人攻擊"的風(fēng)險(xiǎn)驾孔,而瀏覽器跳轉(zhuǎn)時(shí),錨點(diǎn)不會(huì)發(fā)到服務(wù)器进统,就減少了泄漏令牌的風(fēng)險(xiǎn)。

這種方式把令牌直接傳給前端浪听,是很不安全的螟碎。因此,只能用于一些安全要求不高的場景迹栓,并且令牌的有效期必須非常短掉分,通常就是會(huì)話期間(session)有效,瀏覽器關(guān)掉克伊,令牌就失效了酥郭。

第三種方式:密碼式

如果你高度信任某個(gè)應(yīng)用,RFC 6749 也允許用戶把用戶名和密碼愿吹,直接告訴該應(yīng)用不从。該應(yīng)用就使用你的密碼,申請(qǐng)令牌犁跪,這種方式稱為"密碼式"(password)椿息。

第一步,A 網(wǎng)站要求用戶提供 B 網(wǎng)站的用戶名和密碼坷衍。拿到以后寝优,A 就直接向 B 請(qǐng)求令牌。

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)站驗(yàn)證身份通過后,直接給出令牌铅协。注意扔役,這時(shí)不需要跳轉(zhuǎn),而是把令牌放在 JSON 數(shù)據(jù)里面警医,作為 HTTP 回應(yīng)亿胸,A 因此拿到令牌坯钦。

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

第四種方式:憑證式

最后一種方式是憑證式(client credentials)序仙,適用于沒有前端的命令行應(yīng)用突颊,即在命令行下請(qǐng)求令牌。

第一步潘悼,A 應(yīng)用在命令行向 B 發(fā)出請(qǐng)求律秃。

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 確認(rèn) A 的身份棒动。

第二步,B 網(wǎng)站驗(yàn)證通過以后宾添,直接返回令牌船惨。

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

令牌的使用

A 網(wǎng)站拿到令牌以后扛邑,就可以向 B 網(wǎng)站的 API 請(qǐng)求數(shù)據(jù)了怜浅。

此時(shí),每個(gè)發(fā)到 API 的請(qǐng)求蔬崩,都必須帶有令牌海雪。具體做法是在請(qǐng)求的頭信息,加上一個(gè)Authorization字段舱殿,令牌就放在這個(gè)字段里面奥裸。

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

上面命令中,ACCESS_TOKEN就是拿到的令牌沪袭。

更新令牌

令牌的有效期到了湾宙,如果讓用戶重新走一遍上面的流程,再申請(qǐng)一個(gè)新的令牌冈绊,很可能體驗(yàn)不好侠鳄,而且也沒有必要。OAuth 2.0 允許用戶自動(dòng)更新令牌死宣。

具體方法是伟恶,B 網(wǎng)站頒發(fā)令牌的時(shí)候,一次性頒發(fā)兩個(gè)令牌毅该,一個(gè)用于獲取數(shù)據(jù)博秫,另一個(gè)用于獲取新的令牌(refresh token 字段)潦牛。令牌到期前,用戶使用 refresh token 發(fā)一個(gè)請(qǐng)求挡育,去更新令牌巴碗。

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ù)用于確認(rèn)身份橡淆,refresh_token參數(shù)就是用于更新令牌的令牌。

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

寫到這里,頒發(fā)令牌的四種方式就介紹完了凹嘲。下一篇文章會(huì)編寫一個(gè)真實(shí)的 Demo师倔,演示如何通過 OAuth 2.0 向 GitHub 的 API 申請(qǐng)令牌,然后再用令牌獲取數(shù)據(jù)施绎。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溯革,一起剝皮案震驚了整個(gè)濱河市贞绳,隨后出現(xiàn)的幾起案子谷醉,更是在濱河造成了極大的恐慌,老刑警劉巖冈闭,帶你破解...
    沈念sama閱讀 206,013評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俱尼,死亡現(xiàn)場離奇詭異,居然都是意外死亡萎攒,警方通過查閱死者的電腦和手機(jī)遇八,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來耍休,“玉大人刃永,你說我怎么就攤上這事⊙蚓” “怎么了斯够?”我有些...
    開封第一講書人閱讀 152,370評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長喧锦。 經(jīng)常有香客問我读规,道長,這世上最難降的妖魔是什么燃少? 我笑而不...
    開封第一講書人閱讀 55,168評(píng)論 1 278
  • 正文 為了忘掉前任束亏,我火速辦了婚禮,結(jié)果婚禮上阵具,老公的妹妹穿的比我還像新娘碍遍。我一直安慰自己定铜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,153評(píng)論 5 371
  • 文/花漫 我一把揭開白布雀久。 她就那樣靜靜地躺著宿稀,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赖捌。 梳的紋絲不亂的頭發(fā)上祝沸,一...
    開封第一講書人閱讀 48,954評(píng)論 1 283
  • 那天,我揣著相機(jī)與錄音越庇,去河邊找鬼罩锐。 笑死,一個(gè)胖子當(dāng)著我的面吹牛卤唉,可吹牛的內(nèi)容都是我干的涩惑。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼桑驱,長吁一口氣:“原來是場噩夢啊……” “哼竭恬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起熬的,我...
    開封第一講書人閱讀 36,916評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤痊硕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后押框,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體岔绸,經(jīng)...
    沈念sama閱讀 43,382評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,877評(píng)論 2 323
  • 正文 我和宋清朗相戀三年橡伞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了盒揉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 37,989評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兑徘,死狀恐怖刚盈,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情挂脑,我是刑警寧澤藕漱,帶...
    沈念sama閱讀 33,624評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站最域,受9級(jí)特大地震影響谴分,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜镀脂,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,209評(píng)論 3 307
  • 文/蒙蒙 一牺蹄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薄翅,春花似錦沙兰、人聲如沸氓奈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舀奶。三九已至,卻和暖如春斋射,著一層夾襖步出監(jiān)牢的瞬間育勺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評(píng)論 1 260
  • 我被黑心中介騙來泰國打工罗岖, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涧至,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,401評(píng)論 2 352
  • 正文 我出身青樓桑包,卻偏偏與公主長得像南蓬,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哑了,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,700評(píng)論 2 345

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

  • OAuth 2.0是目前最流行的授權(quán)機(jī)制赘方,用來授權(quán)第三方應(yīng)用,獲取用戶數(shù)據(jù)弱左。 這個(gè)標(biāo)準(zhǔn)比較抽象窄陡,使用了很多術(shù)語,初...
    大風(fēng)吹啊吹的閱讀 212評(píng)論 0 0
  • OAuth 2.0是目前最流行的授權(quán)機(jī)制科贬,用來授權(quán)第三方應(yīng)用泳梆,獲取用戶數(shù)據(jù)鳖悠。 我們現(xiàn)在常用的API接口化都采用了這...
    haokeed閱讀 120評(píng)論 0 0
  • 前言: 我也不知道這個(gè)前言怎么寫榜掌,反正我就是要加。 我為什么要寫這篇文章乘综?前些天調(diào)用一個(gè)普通的搜索...
    機(jī)智的老劉明同志閱讀 550評(píng)論 1 1
  • OAuth 是一個(gè)開放標(biāo)準(zhǔn)的授權(quán)框架憎账,它為第三方應(yīng)用獲取資源所有者在資源所在系統(tǒng)或應(yīng)用上的部分資源提供了一種解決方...
    校長_x閱讀 6,269評(píng)論 0 5
  • 轉(zhuǎn)載阮一峰Oauth2.0文章: OAuth 2.0 的一個(gè)簡單解釋[https://www.ruanyifeng...
    virtual灬zzZ閱讀 425評(píng)論 0 1