- 用途
通過用戶授權,第三方服務訪問用戶存在其他服務上的資源,而不需用戶將用戶名密碼直接傳遞的資源服務器的安全控制協議。
傳統的認證方式是通過用戶/密碼方式,認證成功後根據配置的用戶權限進行相關資源的訪問和操作,這樣用戶必須在該網站註冊才能做其他的事情。現在我們可以看到,很多網站都支持微信、qq登錄,這樣應用不需要用戶單獨註冊,僅通過與騰訊進行對接,用戶通過其在騰訊已有的賬號進行認證即可,當然前提是,騰訊開發的權限或用戶授權的權限足夠,之後應用就可以根據用戶的授權記錄去騰訊服務器調用數據資源。
參考:
http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html
https://www.cnblogs.com/gavincoder/p/8999954.html
- 角色
Third-party application:第三方應用程序,用戶資源的請求方。
HTTP service:用戶資源持有方,服務提供方。
Resource Owner:資源所有者,即"用戶"。
User Agent:用戶代理,一般指瀏覽器。
Authorization server:認證服務器,即服務提供商專門用來處理認證的服務器。
Resource server:資源服務器,即服務提供商存放用戶生成的資源的服務器。一般與認證服務器爲同一臺。
- 流程
(A)用戶打開客戶端以後,獲取存儲在其他服務上的資源,客戶端將用戶導向認證界面,要求用戶給予授權。
(B)用戶同意給予客戶端授權。
(C)客戶端使用上一步獲得的授權,向認證服務器申請令牌。
(D)認證服務器對客戶端進行認證以後,確認無誤,同意發放令牌。
(E)客戶端使用令牌,向資源服務器申請獲取資源。
(F)資源服務器確認令牌無誤,同意向客戶端開放資源。
- 模式
授權碼模式(authorization code)
簡化模式(implicit)
密碼模式(resource owner password credentials)
客戶端模式(client credentials)
授權碼模式:
(A)用戶訪問客戶端,後者將前者導向認證服務器。
由資源提供方提供具體的認證地址: GET /authorize?response_type=code&client_id=<client_id>&state=<state>&redirect_uri=<redirect_uri>
- response_type:表示授權類型,必選項,此處的值固定爲"code"
- client_id:表示客戶端的ID,必選項
- redirect_uri:表示重定向URI,可選項
- scope:表示申請的權限範圍,可選項
- state:表示客戶端的當前狀態,可以指定任意值,認證服務器會原封不動地返回這個值。
(B)用戶選擇是否給予客戶端授權。
一般需要用戶輸入用戶名/密碼認證,或者通過本地實例直接認證。
(C)假設用戶給予授權,認證服務器將用戶導向客戶端事先指定的"重定向URI"(redirection URI),同時附上一個授權碼。
資源提供方在用戶認證無誤後,會調用A步驟中的<redirect_uri>並附帶code、state參數。
- code:表示授權碼,必選項。該碼的有效期應該很短,通常設爲10分鐘,客戶端只能使用該碼一次,否則會被授權服務器拒絕。該碼與客戶端ID和重定向URI,是一一對應關係。
- state:如果客戶端的請求中包含這個參數。
(D)客戶端收到授權碼,附上早先的"重定向URI",向認證服務器申請令牌。這一步是在客戶端的後臺的服務器上完成的,對用戶不可見。
第三方服務器在後臺向資源提供方發送請求,獲取令牌,請求地址又提供方定義,攜帶以下參數。
POST /token grant_type=authorization_code&code=<code>&redirect_uri=<redirect_uri>&client_id=<client_id>
- grant_type:表示使用的授權模式,必選項,此處的值固定爲"authorization_code"。
- code:表示上一步獲得的授權碼,必選項。
- redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該參數值保持一致。
- client_id:表示客戶端ID,必選項。
(E)認證服務器覈對了授權碼和重定向URI,確認無誤後,向客戶端發送訪問令牌(access token)和更新令牌(refresh token)。
認證服務器接收post請求後進行認證,並返回如下內容:
- access_token:表示訪問令牌,必選項。
- token_type:表示令牌類型,該值大小寫不敏感,必選項,可以是bearer類型或mac類型。
- expires_in:表示過期時間,單位爲秒。如果省略該參數,必須其他方式設置過期時間。
- refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。
- scope:表示權限範圍,如果與客戶端申請的範圍一致,此項可省略
(F)第三方服務器每次請求攜帶access_token進行資源訪問
簡化模式:
授權碼模式(authorization code)是功能最完整、流程最嚴密的授權模式。它的特點就是通過客戶端的後臺服務器,與"服務提供商"的認證服務器進行互動。
(A)客戶端將用戶導向認證服務器。
客戶端發送請求需要的參數:
- response_type:表示授權類型,此處的值固定爲"token",必選項。
- client_id:表示客戶端的ID,必選項。
- redirect_uri:表示重定向的URI,可選項。
- scope:表示權限範圍,可選項。
- state:表示客戶端的當前狀態,可以指定任意值,認證服務器會原封不動地返回這個值。
(B)用戶決定是否給於客戶端授權。
(C)假設用戶給予授權,認證服務器將用戶導向客戶端指定的"重定向URI",並在URI的Hash部分包含了訪問令牌。
重定向URI包含如下參數,通過hash方式傳遞(#):
- access_token:表示訪問令牌,必選項。
- token_type:表示令牌類型,該值大小寫不敏感,必選項。
- expires_in:表示過期時間,單位爲秒。如果省略該參數,必須其他方式設置過期時間。
- scope:表示權限範圍,如果與客戶端申請的範圍一致,此項可省略。
- state:如果客戶端的請求中包含這個參數,認證服務器的迴應也必須一模一樣包含這個參數。
(D)瀏覽器向資源服務器發出請求,其中不包括上一步收到的Hash值。
(E)資源服務器返回一個網頁,其中包含的代碼可以獲取Hash值中的令牌。
(F)瀏覽器執行上一步獲得的腳本,提取出令牌。
與授權碼模式相比,此模式不需要在後臺通過授權碼獲取令牌,而是直接通過前端截取令牌,然後在訪問資源時攜帶。
(G)瀏覽器將令牌發給客戶端。
密碼模式:
密碼模式(Resource Owner Password Credentials Grant)中,用戶向客戶端提供自己的用戶名和密碼。客戶端使用這些信息,向"服務商提供商"索要授權。在這種模式中,用戶必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。這通常用在用戶對客戶端高度信任的情況下,比如客戶端是操作系統的一部分,或者由一個著名公司出品。而認證服務器只有在其他授權模式無法執行的情況下,才能考慮使用這種模式。
(A)用戶向客戶端提供用戶名和密碼。
(B)客戶端將用戶名和密碼發給認證服務器,向後者請求令牌。
請求需要的參數:
- grant_type:表示授權類型,此處的值固定爲"password",必選項。
- username:表示用戶名,必選項。
- password:表示用戶的密碼,必選項。
- scope:表示權限範圍,可選項。
(C)認證服務器確認無誤後,向客戶端提供訪問令牌。
返回憑證:
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA",
"example_parameter":"example_value"
}
客戶端模式:
客戶端模式(Client Credentials Grant)指客戶端以自己的名義,而不是以用戶的名義,向"服務提供商"進行認證。嚴格地說,客戶端模式並不屬於OAuth框架所要解決的問題。在這種模式中,用戶直接向客戶端註冊,客戶端以自己的名義要求"服務提供商"提供服務,其實不存在授權問題。
(A)客戶端向認證服務器進行身份認證,並要求一個訪問令牌。
包含參數:
- granttype:表示授權類型,此處的值固定爲"clientcredentials",必選項。
- scope:表示權限範圍,可選項。
(B)認證服務器確認無誤後,向客戶端提供訪問令牌。
生成令牌:
{
"access_token":"2YotnFZFEjr1zCsicMWpAA",
"token_type":"example",
"expires_in":3600,
"example_parameter":"example_value"
}
令牌更新:
主要參數:
- granttype:表示使用的授權模式,此處的值固定爲"refreshtoken",必選項。
- refresh_token:表示早前收到的更新令牌,必選項。
- scope:表示申請的授權範圍,不可以超出上一次申請的範圍,如果省略該參數,則表示與上一次一致。
- 示例
以簡書調用微博進行授權爲示例:
1)進入簡書登錄界面
2) 點擊微博進入授權界面
同時關注地址欄,解碼後如下,可見是通過授權碼模式進行授權
https://api.weibo.com/oauth2/authorize?client_id=1881139527&redirect_uri=http://www.jianshu.com/users/auth/weibo/callback&response_type=code&state={}
3)微博會向上面的redirect_uri發送請求,同時攜帶code參數,下面是抓包數據
http://www.jianshu.com/users/auth/weibo/callback?code=xxxx
4)簡書獲取code,並在後臺向微博發送POST請求,其中會攜帶以下參數:
POST https://api.weibo.com/oauth2/access_token
- client_id:在微博開放平臺申請的應用 ID
- client_secret:在微博開放平臺申請時提供的APP Secret
- grant_type:需要填寫authorization_code
- code:上一步獲得的 code
- redirect_uri:回調地址,需要與註冊應用裏的回調地址以及第一步的 redirect_uri 參數一致
5)微博返回令牌相關的數據,格式如下:
{ "access_token": "ACCESS_TOKEN",//Token 的值 "refresh_token": "REFRESH_TOKEN",//刷新token "expires_in": 3600,//過期時間 "uid":"id"//當前授權用戶的UID。 }
6)簡書通過access_token就可以訪問微博接口,獲取根據授權獲取數據或進行一些操作
7)簡書獲取獲取用戶信息,並在其系統 內部完成認證
8)若令牌過期,則可以通過refresh_tkoen獲取新的令牌,如果失敗則重新授權
由於以上一些流程是在系統內部完成,同時微博是https請求,所以沒有抓取打請求信息,所以沒有截圖。