什么是OAuth2
是開放授權(quán)的一個(gè)標(biāo)準(zhǔn),旨在讓用戶允許第三方應(yīng)用去訪問改用戶在某服務(wù)器中的特定私有資源隘冲,而可以不提供其在某服務(wù)器的賬號密碼給到第三方應(yīng)用
通俗的話可以這樣去理解钳吟,假如你們公司正在開發(fā)一個(gè) 第三方應(yīng)用XXX坤按,該應(yīng)用會需要在微信中分享出來一個(gè)活動頁考传,該活動需要讓微信用戶去參與招拙,你們的應(yīng)用需要收集到用戶的姓名其屏,頭像喇勋,地域等信息,那么問題來了偎行?你的應(yīng)用如何才能拿到所有參與活動的微信用戶的基本信息呢?
根據(jù)以上示例川背,可以將OAuth2分為四個(gè)角色:
Resource Owner:資源所有者 即上述中的微信用戶
Resource Server:資源服務(wù)器 即上述中的微信服務(wù)器,提供微信用戶基本信息給到第三方應(yīng)用
Client:第三方應(yīng)用客戶端 即上述中你公司正在開發(fā)的第三方應(yīng)用
Authorication Server:授權(quán)服務(wù)器 該角色可以理解為管理其余三者關(guān)系的中間層
不難看出蛤袒,OAuht2 解決問題的關(guān)鍵在于使用授權(quán)服務(wù)器
提供一個(gè)訪問憑據(jù)
給到第三方應(yīng)用
熄云,讓第三方應(yīng)用
可以在不知道資源所有者
在資源服務(wù)器上的賬號和密碼
的情況下,能獲取到資源所有者
在資源服務(wù)器
上的受保護(hù)資源
妙真,這里的受保護(hù)資源就是微信用戶的姓名以及頭像等信息
缴允。
OAuth2 授權(quán)流程
引用 blackheart 博主的流程圖
拿上述的獲取微信用戶信息示例來說
微信用戶a,訪問第三方應(yīng)用分享到微信中的活動頁面珍德,第三方應(yīng)用即向微信授權(quán)服務(wù)器 發(fā)起授權(quán)請求以獲取該微信用戶a在微信服務(wù)器上的姓名练般,頭像等基本信息(私有資源)
微信授權(quán)服務(wù)器
接收到第三方應(yīng)用的授權(quán)請求
(包含第三方應(yīng)用的回調(diào)地址的)矗漾,并引導(dǎo)
用戶確認(rèn)授權(quán)
(也可以選擇用戶靜默授權(quán)
)后,返回授權(quán)許可(code)給到第三方應(yīng)用(根據(jù)授權(quán)請求傳入的回調(diào)地址
)第三方應(yīng)用
拿到
授權(quán)許可code
后薄料,再次向微信授權(quán)服務(wù)器發(fā)起訪問令牌
的請求(攜帶身份app_id
等)微信
授權(quán)服務(wù)器
驗(yàn)證第三方應(yīng)用的身份
以及授權(quán)許可code
敞贡,驗(yàn)證通過后將下發(fā)訪問令牌access_code,此外還有刷新令牌
以及令牌過期時(shí)間
等信息給到第三方應(yīng)用第三方應(yīng)用
拿到訪問令牌
后向微信資源服務(wù)器發(fā)起請求資源
摄职,即請求微信用戶a的姓名誊役,頭像,地域
等基本信息微信資源服務(wù)器根據(jù)訪問令牌谷市,返回微信用戶a的基本信息給到第三方應(yīng)用蛔垢。
至此,整套授權(quán)流程結(jié)束歌懒,可以看出訪問令牌
是整個(gè)流程中的核心
訪問令牌:可以理解為對第三方應(yīng)用可以在微信資源服務(wù)器中得到微信用戶a的哪些信息的一個(gè)抽象集合啦桌,微信資源服務(wù)器拿到訪問令牌后就知道是哪個(gè)第三方應(yīng)用需要獲取哪個(gè)微信用戶的什么受限資源
如何部署OAuth2
部署OAuth2之前,需要理解上述四種角色之間的關(guān)系及皂,以及每一種角色需要提供那些功能甫男,以及將各種安全性考慮進(jìn)去等等
角色 | 功能 | 備注 |
---|---|---|
認(rèn)證服務(wù)器 | 提供授權(quán)實(shí)現(xiàn) | 提供類似獲取授權(quán)許可(code),訪問令牌(access_token)等接口 |
資源服務(wù)器 | 提供第三方應(yīng)用程序注冊接口以及開放相應(yīng)受保護(hù)資源的API | 第三方應(yīng)用注冊验烧,是為了保證第三方應(yīng)用的來源安全性 |
第三方應(yīng)用 | 申請注冊成為資源服務(wù)器的第三方應(yīng)用以及消費(fèi)資源服務(wù)器提供的受限資源API | 類似微信公眾號申請操作板驳,由授權(quán)服務(wù)器提供標(biāo)識第三方應(yīng)用的 app_id & app_secret |
用戶 | 不需要做什么額外的改動,只需要點(diǎn)擊確認(rèn)授權(quán)即可 |
一般情況下授權(quán)服務(wù)器的工作由資源服務(wù)器提供碍拆,主要提供兩類接口
- 授權(quán)接口:接受第三方應(yīng)用的授權(quán)請求若治,引導(dǎo)用戶到資源服務(wù)器完成登陸授權(quán)的過程
- 獲取訪問令牌接口:使用授權(quán)接口提供的許可憑證來頒發(fā)用戶的訪問令牌給到第三方應(yīng)用,或者又第三方應(yīng)用更新過期的訪問令牌感混。
除此之外端幼,還需要提供一個(gè)讓第三方應(yīng)用程序注冊的管理后臺,當(dāng)?shù)谌綉?yīng)用注冊后會給到第三方應(yīng)用一個(gè)app_id & app_secret 弧满,app_secret是第三方應(yīng)用程序的私鑰婆跑,不允許在授權(quán)過程中傳遞的,主要用戶安全加密用庭呜。
OAuth2中的有哪些授權(quán)許可
前面的示例中滑进,第三方應(yīng)用需要首先請求授權(quán)服務(wù)器以獲取到授權(quán)許可code募判,再通過授權(quán)許可code去請求訪問令牌渴丸,OAuth2中定義了四種許可類型以擴(kuò)展OAuth2的機(jī)制
- 授權(quán)碼 Authorization Code
- 隱式許可 Implicit
- 資源所有者密碼憑證 Resource Owner Password Credentials
- 客戶端憑證 Client Credentials
Authorization Code
授權(quán)碼是OAuth2中最常用的一種授權(quán)許可類型虽惭,要求第三方應(yīng)用需要有可公開訪問的服務(wù)器來接收授權(quán)許可code缝彬,即上述中所說的回調(diào)地址。
引用 blackheart 博主的流程圖
簡要闡述一下各步驟
- 授權(quán)碼請求
第三方應(yīng)用使用用戶代理(瀏覽器非洲,或自己的服務(wù)器)訪問微信授權(quán)服務(wù)器提供的一個(gè)url褐奴,該url就是提供獲取授權(quán)碼的url锯仪,第三方應(yīng)用需要傳遞一下參數(shù)
response_type:(必傳)此時(shí)為"code"
app_id:(必傳)微信服務(wù)器下發(fā)的標(biāo)識第三方應(yīng)用的
redirect_uri:(必傳)授權(quán)成功后的重定向地址
scope:(可選)標(biāo)識授權(quán)范圍
state:(推薦)第三方應(yīng)用提供的一個(gè)字符串,微信授權(quán)服務(wù)器會原樣返回
示例請求
GET /authorize?response_type=code&app_id=wx201800a28199&state=wilson&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Foauth2&scope=user,photo HTTP/1.1
- 授權(quán)碼返回
微信授權(quán)服務(wù)器驗(yàn)證第三方應(yīng)用再上一步中傳遞的參數(shù)疯淫,確認(rèn)無誤后會提供一個(gè)頁面給微信用戶a登錄或者手動確認(rèn)授權(quán)操作地来,操作超過后微信授權(quán)服務(wù)器會根據(jù)redirect_uri重定向到該地址,并攜帶下發(fā)的授權(quán)許可code
類似重定向地址
HTTP/1.1 302 Found
Location: https://client.example.com/oauth2?code=SplxlOBeZQQYbYS6WxSbIA&state=wilson
- 訪問令牌請求
第三方應(yīng)用根據(jù)上一步拿到的授權(quán)碼code以及app_id熙掺,重定向地址等參數(shù),再次請求微信授權(quán)服務(wù)器咕宿,請求獲取訪問令牌access_token
grant_type:(必傳)值為"authorization_code"
code:(必傳)值為上一步獲取到的授權(quán)碼code
redirect_uri:(必傳)必須和第一步獲取授權(quán)碼中的一致
app_id:(必傳)標(biāo)識第三方應(yīng)用id
請求示例如下
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&app_id=wx201800a28199&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Foauth2
- 訪問令牌返回
微信授權(quán)服務(wù)器返回訪問令牌和一些刷新令牌币绩,令牌過期時(shí)間等信息給到第三方應(yīng)用
返回示例如下:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
- 受限資源獲取
第三方應(yīng)用根據(jù)訪問令牌去微信資源服務(wù)器獲取微信用戶a的基本信息。
Implicit
此種授權(quán)方式是授權(quán)碼方式的簡化版本府阀,其中省略了頒發(fā)授權(quán)碼code給第三方應(yīng)用的步驟缆镣,通過一次請求微信授權(quán)服務(wù)器直接返回訪問令牌以及刷新令牌等信息,適用于沒有server服務(wù)器來接受處理授權(quán)碼的第三方應(yīng)用
- 授權(quán)請求
請求參數(shù)示例
response_type:(必填)此處值為 "token"
app_id:(必傳)微信服務(wù)器下發(fā)的標(biāo)識第三方應(yīng)用的
redirect_uri:(必傳)授權(quán)成功后的重定向地址
scope:(可選)標(biāo)識授權(quán)范圍
state:(推薦)第三方應(yīng)用提供的一個(gè)字符串试浙,微信授權(quán)服務(wù)器會原樣返回
請求url示例
GET /authorize?response_type=token&app_id=wx201800a28199&state=wilson&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Foauth2&scope=user,photo HTTP/1.1
- 授權(quán)返回
返回參數(shù)示例
access_token: 訪問令牌
refresh_token:刷新令牌
expire_in:過期時(shí)間
返回url示例
HTTP/1.1 302 Found
Location:
http://client.example.com/oauth2#access_token=2YotnFZFEjr1zCsicMWpAA&state=wilson&expires_in=3600
Resource Owner Password Credentials Grant
該授權(quán)模式是第三方應(yīng)用直接使用微信用戶a的賬號+密碼來直接請求微信授權(quán)服務(wù)器access_token董瞻,該模式適用于微信資源服務(wù)器高度信任第三方client的情況
- 訪問令牌請求
請求參數(shù)示例
grant_type:(必填)值固定為 "password"
user_name:(必填)微信用戶登錄名
password:(必填)用戶登錄密碼
scope:可選 標(biāo)識授權(quán)范圍
請求url 示例
POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
grant_type=password&username=blackheart&password=1234
- 訪問令牌返回
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
Client Credentials Grant
此類型更加簡化,第三方應(yīng)用直接使用自己的名義而不是微信用戶a的名義去要求訪問微信資源服務(wù)器的一些受保護(hù)資源田巴,針對第三方應(yīng)用獲取微信資源服務(wù)器下的所有微信用戶的信息而不是單個(gè)微信用戶a的信息
- 授權(quán)請求(以自己的名義)
請求參數(shù)示例
grant_type:(必填)值固定為 "client_credentials"
scope:可選 標(biāo)識授權(quán)范圍
- 授權(quán)返回
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
OAuth2 刷新令牌
在上述第三方應(yīng)用獲取到訪問令牌后钠糊,一般會同時(shí)得到一個(gè)過期時(shí)間以及刷新令牌,以在訪問令牌失效時(shí)可以由第三方應(yīng)用自動獲取新的訪問令牌壹哺,而不是由微信用戶a再次授權(quán)一遍抄伍。
當(dāng)訪問令牌過期時(shí),由第三方應(yīng)用調(diào)用微信授權(quán)服務(wù)器的刷新令牌接口管宵,傳遞以下參數(shù)即可截珍。
grant_type:必填 值為 "refresh_token"
refresh_token:必填 值為第三方應(yīng)用得到訪問令牌同時(shí)拿到的刷新令牌
- 刷新令牌請求
POST /token HTTP/1.1
Host: server.example.com
grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
- 刷新令牌返回
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
這樣就可以一直使用有效的訪問令牌啦
OAuth2 安全問題
互聯(lián)網(wǎng)安全應(yīng)引起足夠的重視,防止出現(xiàn)重大事故
- 要求Authorization server進(jìn)行有效的第三方應(yīng)用身份驗(yàn)證
- app_serect,access_token,refresh_token,code等敏感信息的安全存儲(不得泄露給第三方)箩朴、傳輸通道的安全性(TSL的要求)
- 維持refresh_token和第三方應(yīng)用的綁定岗喉,刷新失效機(jī)制
- 維持Authorization Code和第三方應(yīng)用的綁定,這也是state參數(shù)為什么是推薦的一點(diǎn)炸庞,以防止CSRF
- 保證上述各種令牌信息的不可猜測行钱床,以防止被猜測得到