OAuth
協議爲用戶資源的受權提供了一個安全的、開放而又簡易的標準。與以往的受權方式不一樣之處是OAuth
的受權不會使第三方觸及到用戶的賬號信息(如用戶名與密碼),即第三方無需使用用戶的用戶名與密碼就能夠申請得到該用戶資源的受權,所以OAuth
是安全的。OAuth
是Open Authorization
的簡寫。sql
OAuth
自己不存在一個標準的實現,後端開發者本身根據實際的需求和標準的規定實現。其步驟通常以下:json
token
)任何身份認證,本質上都是基於對請求方的不信任所產生的。同時,請求方是信任被請求方的,例如用戶請求服務時,會信任服務方。segmentfault
因此,身份認證就是爲了解決身份的可信任問題。後端
在OAuth
中,簡單來講有三方:用戶(這裏是指屬於服務方的用戶
)、服務方、第三方應用。緩存
服務方不信任用戶,因此須要用戶提供密碼或其餘可信憑據;安全
服務方不信任第三方,因此須要第三方提供自已交給它的憑據(一般的一些安全簽名之類的就是);服務器
用戶部分信任第三方,因此用戶願意把自已在服務方里的某些服務交給第三方使用,但不肯意把自已在服務方的密碼交給第三方;微信
在oauth2.0
的流程中,用戶登陸了第三方的系統後,會先跳去服務方獲取一次性用戶受權憑據,再跳回來把它交給第三方,第三方的服務器會把受權憑據以及服務方給它的的身份憑據一塊兒交給服務方,這樣,服務方一能夠肯定第三方獲得了用戶對這次服務的受權(根據用戶受權憑據),二能夠肯定第三方的身份是能夠信任的(根據身份憑據),因此,最終的結果就是,第三方順利地從服務方獲取到了這次所請求的服務。app
從上面的流程中能夠看出,oauth2.0
完整地解決掉了用戶、服務方、第三方 在某次服務時這三者之間的信任問題。url
- Resource Owner(資源擁有者:用戶)
- Client (第三方接入平臺:請求者)
- Resource Server (服務器資源:數據中心)
- Authorization Server (認證服務器)
Oauth2.0基本流程:
原理很簡單,用戶訪問App
,App
訪問Authorization Server
請求權限,
Authorization Server
獲得用戶贊成後,返回token
,
App
經過這個token
向Authorization Server
索要數據,
App
只能從Authorization Server
這個中介獲取服務器數據,而沒法直接訪問Resource Server
。
客戶端必須獲得用戶的受權(authorization grant
),才能得到令牌(access token
)。OAuth 2.0
定義了四種受權方式。
- 受權碼模式(
authorization code
)- 簡化模式(
implicit
)- 密碼模式(
resource owner password credentials
)- 客戶端模式(
client credentials
)
受權碼模式(authorization code
)是功能最完整、流程最嚴密的受權模式。它的特色就是經過客戶端的後臺服務器,與"服務提供商"的認證服務器進行互動。
它的步驟以下:
- 用戶訪問客戶端,後者將前者導向認證服務器。
- 用戶選擇是否給予客戶端受權。
- 假設用戶給予受權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection URI),同時附上一個受權碼。
- 客戶端收到受權碼,附上早先的"重定向URI",向認證服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見。
- 認證服務器覈對了受權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)。
下面是上面這些步驟所須要的參數。
步驟1: 客戶端申請認證的URI,包含如下參數:
- response_type:表示受權類型,必選項,此處的值固定爲"code"
- client_id:表示客戶端的ID,必選項。(
如微信受權登陸,此ID是APPID
)- redirect_uri:表示重定向URI,可選項
- scope:表示申請的權限範圍,可選項 state:表示客戶端的當前狀態,能夠指定任意值,認證服務器會原封不動地返回這個值。
例子:
GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyz &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1 HTTP/1.1 Host: server.example.com
對比微信網頁掃描受權請求CODE
https://open.weixin.qq.com/connect/qrconnect?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect
步驟3:服務器迴應客戶端的URI,包含如下參數:
- code:表示受權碼,必選項。該碼的有效期應該很短,一般設爲10分鐘,客戶端
只能使用該碼一次
,不然會被受權服務器拒絕。該碼與客戶端ID和重定向URI,是一一對應關係。- state:若是客戶端的請求中包含這個參數,認證服務器的迴應也必須如出一轍包含這個參數。
例子:
HTTP/1.1 302 Found Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA &state=xyz
步驟4:客戶端向認證服務器申請令牌的HTTP請求,包含如下參數:
- grant_type:表示使用的受權模式,必選項,此處的值固定爲"authorization_code"。
- code:表示上一步得到的受權碼,必選項。
- redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該參數值保持一致。
- client_id:表示客戶端ID,必選項。
例子:
POST /token HTTP/1.1 Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb
步驟5:認證服務器發送的HTTP回覆,包含如下參數:
- access_token:表示訪問令牌,必選項。
- token_type:表示令牌類型,該值大小寫不敏感,必選項,能夠是bearer類型或mac類型。
- expires_in:表示過時時間,單位爲秒。若是省略該參數,必須其餘方式設置過時時間。
- refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。
- scope:表示權限範圍,若是與客戶端申請的範圍一致,此項可省略。
例子:
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store Pragma: no-cache { "access_token":"2YotnFZFEjr1zCsicMWpAA", "token_type":"example", "expires_in":3600, "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA", "example_parameter":"example_value" }
從上面代碼能夠看到,相關參數使用JSON格式發送(Content-Type: application/json
)。此外,HTTP頭信息中明確指定不得緩存。
若是用戶訪問的時候,客戶端的"訪問令牌"已通過期,則須要使用"更新令牌"申請一個新的訪問令牌。
客戶端發出更新令牌的HTTP請求,包含如下參數:
例子:
POST /token HTTP/1.1
Host: server.example.com Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW Content-Type: application/x-www-form-urlencoded grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA
原文連接:https://segmentfault.com/a/1190000010540911?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io