談談OAuth1,OAuth2異同


##一、寫在前面
在收集資料時,我查詢和學習了許多介紹OAuth的文章,這些文章有好有壞,但大多是從個例出發。因此我想從官方文檔出發,結合在stackoverflow上的一些討論,一並整理一下。整理的內容分為OAuth1.0a和OAuth2兩部分。

OAuth 1.0a:One Leg ->Two Leg -> Three Legged
OAuth 2:Two Leg ->Three Legged (附:Refresh Token的方式)

這兩種模式都是按箭頭從左往右安全性遞增,其實現也會相對復雜。關於官方的這種leg(腿?)的說法,在中文翻譯中比較少有文章提及。下面分別來介紹OAuth的這5種授權流程。

##二、OAuth1.0a
2.1 OAuth 1.0a (One Leg)

  1. 應用給服務器發送一個簽名請求,附帶以下參數:
    • oauth_token Empty String
    • oauth_consumer_key
    • oauth_timestamp
    • oauth_nonce
    • oauth_signature
    • oauth_signature_method
    • oauth_version Optional
  2. 服務驗證並授予對資源的訪問
  3. 應用程序利用請求的資源

2.2 OAuth 1.0a (Two Legs)

  1. 應用發送一個簽名請求,以獲取 Request Token:
    • oauth_consumer_key
    • oauth_timestamp
    • oauth_nonce
    • oauth_signature
    • oauth_signature_method
    • oauth_version Optional
  2. 服務器返回Request Token:
    • oauth_token
    • oauth_token_secret
    • Additional Parameters / Arguments
  3. 發送簽名請求,用Request Token換取Access Token
    • oauth_token Request Token
    • oauth_consumer_key
    • oauth_nonce
    • oauth_signature
    • oauth_signature_method
    • oauth_version
  4. 服務器返回Access Token和Token Secret
  5. 應用通過Access Token和Token Secret利用請求的資源

2.3 OAuth 1.0a (Three Legged)

  1. 應用發送一個簽名請求,以獲取 Request Token:
    • oauth_consumer_key
    • oauth_timestamp
    • oauth_nonce
    • oauth_signature
    • oauth_signature_method
    • oauth_version Optional
  2. 服務器返回Request Token:
    • oauth_token
    • oauth_token_secret
    • oauth_callback_confirmed
    • … Additional Parameters / Arguments
  3. 發送給用戶授權的URL
    • oauth_token
  4. 提示用戶進行授權
  5. 用戶進行授權
  6. 授權結束后返回應用,附帶上:
    • oauth_token
    • oauth_verifier
  7. 發送簽名請求,用Request Token換取Access Token
    • oauth_token Request Token
    • oauth_consumer_key
    • oauth_nonce
    • oauth_signature
    • oauth_signature_method
    • oauth_version
    • oauth_verifier
  8. 服務器返回Access Token和Token Secret
  9. 應用通過Access Token和Token Secret利用請求的資源

##三、OAuth2

3.1 OAuth 2 (Two Legged)

3.1.1 客戶端憑據方式

  1. 應用發送請求到服務器:
    • grant_type = client_credentials
      如果沒有使用Authorization(Authorization: Basic Base64(client_id:client_secret)) 的header,必須附帶參數為:
    • client_id
    • client_secret
  2. 服務器以Access Token回應
    • access_token
    • expires_in
    • token_type

3.1.2 隱式授予方式

  1. 應用發送請求到服務器:
    • response_type = token
    • redirect_uri This is a server-side Redirection URI hosted by the provider or yourself.
    • scope
    • state Optional
    • client_id
  2. 用戶可根據需要授權。
    • username
    • password
  3. 服務器將響應包含access_token在內的redirect_uri
  4. 應用程序跳轉至redirect_uri
  5. redirect_uri將響應一段腳本或HTML片段。響應的腳本或HTML片段包含參數access_token,還有您可能需要的任何其他參數。

3.1.3 資源所有者密碼方式

  1. 應用向資源所有者請求憑證
    • username
    • password
  2. 應用使用憑證,向服務器發送請求
    • 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
  3. 服務器返回Access Toke
    • access_token
    • expires_in
    • token_type

3.2 OAuth 2 (Three Legged)

  1. 應用重定向用戶到授權服務:
    • 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
  2. 用戶登錄服務器並確認授權給應用
  3. 服務器重定向用戶到redirect_url ,附帶參數:
    • code
    • state
  4. 應用拿到code,並換取Access Token
    • client_id
    • client_secret
    • code
    • redirect_uri Optional;
    • grant_type = “authorization_code”
  5. 如果的client_id和client_secret是有效的,服務器將調用一個回調redirect_url,包含ACCESS_TOKEN
    • access_token
    • expires_in
    • refresh_token
  6. 應用保存ACCESS_TOKEN,在隨后的請求中使用。通常這個值被存儲在session或或cookie,需要時作為授權請求的參數。

3.3 OAuth 2 (Refresh Token 刷新token)

在OAuth2中,Token會有過期時間,我們必須去refresh_token,使用其他一些先前獲得的參數,生成一個新的token。這是一個容易得多的流程。

  1. 創建刷新令牌請求
    • grant_type = “refresh_token”
    • scope Optional; Cannot have any new scopes not previously defined.
    • refresh_token
    • client_id
    • client_secret
  2. 服務驗證和響應以下參數:
    • access_token
    • issued_at

##四、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保護


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM