##1、寫在前面
在收集資料時,我查詢和學習了許多介紹OAuth的文章,這些文章有好有壞,但大可能是從個例出發。所以我想從官方文檔出發,結合在stackoverflow上的一些討論,一併整理一下。整理的內容分爲OAuth1.0a和OAuth2兩部分。html
OAuth 1.0a:One Leg ->Two Leg -> Three Legged
OAuth 2:Two Leg ->Three Legged (附:Refresh Token的方式)瀏覽器
這兩種模式都是按箭頭從左往右安全性遞增,其實現也會相對複雜。關於官方的這種leg(腿?)的說法,在中文翻譯中比較少有文章說起。下面分別來介紹OAuth的這5種受權流程。安全
##2、OAuth1.0a
2.1 OAuth 1.0a (One Leg)服務器
- 應用給服務器發送一個簽名請求,附帶如下參數:
- oauth_token Empty String
- oauth_consumer_key
- oauth_timestamp
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version Optional
- 服務驗證並授予對資源的訪問
- 應用程序利用請求的資源
2.2 OAuth 1.0a (Two Legs)cookie
- 應用發送一個簽名請求,以獲取 Request Token:
- oauth_consumer_key
- oauth_timestamp
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version Optional
- 服務器返回Request Token:
- oauth_token
- oauth_token_secret
- Additional Parameters / Arguments
- 發送簽名請求,用Request Token換取Access Token
- oauth_token Request Token
- oauth_consumer_key
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version
- 服務器返回Access Token和Token Secret
- 應用經過Access Token和Token Secret利用請求的資源
2.3 OAuth 1.0a (Three Legged)session
- 應用發送一個簽名請求,以獲取 Request Token:
- oauth_consumer_key
- oauth_timestamp
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version Optional
- 服務器返回Request Token:
- oauth_token
- oauth_token_secret
- oauth_callback_confirmed
- … Additional Parameters / Arguments
- 發送給用戶受權的URL
- 提示用戶進行受權
- 用戶進行受權
- 受權結束後返回應用,附帶上:
- oauth_token
- oauth_verifier
- 發送簽名請求,用Request Token換取Access Token
- oauth_token Request Token
- oauth_consumer_key
- oauth_nonce
- oauth_signature
- oauth_signature_method
- oauth_version
- oauth_verifier
- 服務器返回Access Token和Token Secret
- 應用經過Access Token和Token Secret利用請求的資源
##3、OAuth2app
3.1 OAuth 2 (Two Legged)dom
3.1.1 客戶端憑據方式ide
- 應用發送請求到服務器:
- grant_type = client_credentials
若是沒有使用Authorization(Authorization: Basic Base64(client_id:client_secret)) 的header,必須附帶參數爲:
- client_id
- client_secret
- 服務器以Access Token迴應
- access_token
- expires_in
- token_type
3.1.2 隱式授予方式學習
- 應用發送請求到服務器:
- response_type = token
- redirect_uri This is a server-side Redirection URI hosted by the provider or yourself.
- scope
- state Optional
- client_id
- 用戶可根據須要受權。
- 服務器將響應包含access_token在內的redirect_uri
- 應用程序跳轉至redirect_uri
- redirect_uri將響應一段腳本或HTML片斷。響應的腳本或HTML片斷包含參數access_token,還有您可能須要的任何其餘參數。
3.1.3 資源全部者密碼方式
- 應用向資源全部者請求憑證
- 應用使用憑證,向服務器發送請求
- grant_type = password
- username
- password
url看起來會像這樣:grant_type=password&username=my_username&password=my_password
若是你沒有使用Authorization的header,必須附帶上參數:
- client_id
- client_secret
url看起來會像是:
grant_type=password&username=my_username&password=my_password&client_id=random_string&client_secret=random_secret
- 服務器返回Access Toke
- access_token
- expires_in
- token_type
3.2 OAuth 2 (Three Legged)
- 應用重定向用戶到受權服務:
- client_id
- redirect_uri
- response_type
- state Optional; Unique identifier to protect against CSRF
- scope Optional; what data your application can access.
url看起來會像是:
oauth_service/login/oauth/authorize?client_id=3MVG9lKcPoNINVB&redirect_uri=http://localhost/oauth/code_callback&scope=user
- 用戶登陸服務器並確認受權給應用
- 服務器重定向用戶到redirect_url ,附帶參數:
- 應用拿到code,並換取Access Token
- client_id
- client_secret
- code
- redirect_uri Optional;
- grant_type = 「authorization_code」
- 若是的client_id和client_secret是有效的,服務器將調用一個回調redirect_url,包含ACCESS_TOKEN
- access_token
- expires_in
- refresh_token
- 應用保存ACCESS_TOKEN,在隨後的請求中使用。一般這個值被存儲在session或或cookie,須要時做爲受權請求的參數。
3.3 OAuth 2 (Refresh Token 刷新token)
在OAuth2中,Token會有過時時間,咱們必須去refresh_token,使用其餘一些先前得到的參數,生成一個新的token。這是一個容易得多的流程。
- 建立刷新令牌請求
- grant_type = 「refresh_token」
- scope Optional; Cannot have any new scopes not previously defined.
- refresh_token
- client_id
- client_secret
- 服務驗證和響應如下參數:
##4、stackoverflow上的一些問答
Q:OpenID和OAuth的區別是什麼?
A:OpenID是有關身份驗證(即證實你是誰),OAuth有關受權(即授予訪問權限),推薦博文:從用戶的角度來看OpenID和OAuth
Q:OAuth2與OAuth1不一樣的地方是?有人能夠簡單的解釋的OAuth2和OAuth1之間的區別嗎? OAuth1如今已通過時,應實施的OAuth2?我沒有看到許多實現的OAuth2,大多數仍在使用OAuth,這讓我懷疑的OAuth2的準備使用。是嗎?
A:OAuth2能更好地支持不是基於瀏覽器的應用。對於不是基於瀏覽器的應用程序,這是對OAuth的主要挑戰。例如,在OAuth1.0,桌面應用或手機應用必須引導用戶打開瀏覽器所需的服務,與服務進行身份驗證,並複製令牌從服務返回給應用程序。這裏的主要批評是針對用戶體驗。使用OAuth2.0,能夠用新的方式爲用戶的應用程序得到受權。
OAuth2.0再也不須要客戶端應用程序擁有密鑰。這讓人回想起老的Twitter認證的API,它並不須要應用獲得HMAC哈希令牌和請求字符串。使用OAuth2.0,應用程序能夠經過HTTPS得到令牌。
OAuth2.0的簽名流程簡單得多。沒有更多的特殊解析,排序,或編碼。
OAuth2.0的訪問令牌是「短命」的。一般狀況下,OAuth1.0的訪問令牌能夠存儲一年或一年以上(Twitter歷來沒有讓他們到期)。 OAuth的2.0有刷新令牌的概念。雖然我不能徹底確定這是什麼意思,個人猜想是,您的訪問令牌能夠是短暫存儲的(即基於會話),而你能夠刷新令牌。你使用刷新令牌獲取新的訪問令牌,而不是讓用戶從新受權您的應用程序。
最後,OAuth2.0使得負責處理的OAuth請求的服務器和處理用戶的受權服務器之間的角色有一個乾淨的分離。更多信息,在上述的文章中詳述。
Q:OAuth2服務器羣怎麼使用state來防範CSRF?
A:state只是一個隨機的字符串,能夠作這樣的事情:$state = md5(uniqid(rand(), TRUE));在session中記錄satate,以便稍後你能作驗證。一些額外的資料:OAuth2威脅文件模型,特別CSRF保護