全稱 open authorization
相關(guān)術(shù)語
舉個(gè)例子呈宇,第三方應(yīng)用想訪問某用戶關(guān)注的公眾號。
資源所有者:用戶
資源服務(wù)器:騰訊服務(wù)器
授權(quán)服務(wù)器:騰訊認(rèn)證中心
客戶端:第三方應(yīng)用
三種認(rèn)證方式
1. Resource Owner Password Credentials Grant(資源所有者密碼憑據(jù)許可)
用戶直接微信賬號和密碼給第三方應(yīng)用即彪。
2.Implicit Grant(隱式許可)
用戶向騰訊認(rèn)證中心獲取一個(gè) token 。
用戶把這個(gè) token 傳給第三方應(yīng)用活尊,這樣第三方應(yīng)用有權(quán)訪問用戶關(guān)注的公眾號隶校。
缺點(diǎn):taken 放在 URL 的 # 后面,叫 hash fragment蛹锰,明文傳輸深胳。
優(yōu)點(diǎn):只會停留在瀏覽器端, 只有 Javascript 能訪問它宁仔,并且它不會再次通過 http request 發(fā)到別的服務(wù)器稠屠。第三方應(yīng)用的后端服務(wù)器不用參與。
3. Authorization Code Grant(授權(quán)碼許可)
用戶向騰訊認(rèn)證中心獲取一個(gè)授權(quán)碼翎苫。
用戶把這個(gè)授權(quán)碼給第三方應(yīng)用。
第三方把這個(gè)授權(quán)碼傳給騰訊認(rèn)證中心榨了,獲取 token 煎谍。
這樣第三方應(yīng)用有權(quán)訪問用戶關(guān)注的公眾號。
更強(qiáng)保障:
只有在騰訊注冊的第三方應(yīng)用發(fā)出的 token 請求龙屉, 騰訊認(rèn)證中心才認(rèn)為合法呐粘;
還可以讓授權(quán)碼有時(shí)間限制,比如5分鐘失效转捕;
還有可以讓授權(quán)碼只能換一次 token 作岖。
授權(quán)碼許可實(shí)例
我在用新浪賬號登錄知乎時(shí),客戶端是知乎五芝,授權(quán)服務(wù)器是新浪痘儡。
知乎會把我重定向到這樣的頁面:
這個(gè)頁面的 URL 是:
https://api.weibo.com/oauth2/authorize?
scope=email&
state=37326432303439352d313332642d343436332d616434342d323038343833643833366234&
redirect_uri=http%3A%2F%2Fwww.zhihu.com%2Foauth%2Fcallback%2Fsina&
response_type=code&
client_id=3063806388
為了方便閱讀,我把這條 URL 進(jìn)行了多次回車枢步。
第一行:oauth2 說明使用的授權(quán)機(jī)制就是 oauth2 沉删。
第二行:scope 表示申請的權(quán)限范圍,這里是郵箱醉途》澹可選。
第三行:state 表示知乎的當(dāng)前狀態(tài)隘擎,可以指定任意值殴穴,新浪會原封不動地返回這個(gè)值。
第四行:redirect_uri 表示重定向 URI,可選項(xiàng)采幌。
第五行:response_type 固定是 code 恍涂,因?yàn)槭鞘跈?quán)碼許可,必填植榕。
第六行:client_id 這里標(biāo)識知乎再沧,必填。
當(dāng)點(diǎn)擊允許后尊残,新浪會將我導(dǎo)向到知乎事先指定的 redirect_uri炒瘸,同時(shí)附上授權(quán)碼:
https://www.zhihu.com/oauth/callback/sina?
state=37326432303439352d313332642d343436332d616434342d323038343833643833366234&
code=17ad14c9183a5d3fab259d1c96277638
這時(shí)知乎收到授權(quán)碼后,附上 redirect_uri寝衫,向認(rèn)證服務(wù)器申請令牌(token)顷扩。
這一步是在知乎后臺的服務(wù)器上完成的,對用戶不可見慰毅。
新浪核對了授權(quán)碼和重定向 URI隘截,確認(rèn)無誤后,向知乎發(fā)送訪問令牌(access token)和更新令牌(refresh token)汹胃。
授權(quán)碼有效期很短婶芭,通常設(shè)為10分鐘,只能使用一次着饥,再次會被新浪拒絕犀农。
該碼與客戶端 ID 和重定向 URI,是一一對應(yīng)關(guān)系宰掉。