1. 程式人生 > >OAuth認證原理與第三方登入

OAuth認證原理與第三方登入

1.背景

以下例子引用知乎“OAuth 授權的工作原理是怎樣的?足夠安全嗎?”中李天放的回答

假如你在某個網站A上使用微博進行第三方登入,那麼你可以想象新浪微博就是你的家。偶爾你會想讓一些人(第三方應用)去你的家裡幫你做一些事,或取點東西。你可以複製一把鑰匙(使用者名稱和密碼)給他們,但這裡有三個問題: 

(1)別人拿了鑰匙後可以去所有的房間 

(2)別人拿到你的鑰匙後也許會不小心丟到,甚至故意送到它人手裡。這樣你都不知到誰有你家鑰匙。 

(3)過一段時間你也許會想要回自己的鑰匙,但別人不還怎麼辦?  

OAuth 是高階鑰匙:

(1)你可以配置不同許可權的鑰匙。有些只能進大廳(讀取你的微博流)。有些鑰匙可以進儲藏櫃(讀取你的相片)

(2)鑰匙上帶著指紋驗證的(指紋 = appkey)。 收到鑰匙的人只能自己用,不能轉讓

(3)你可以遠端廢除之前發出的鑰匙

總而言之,就是OAuth正是為解決上述問題而誕生。

2.名詞介紹

(1) Third-party application:第三方應用程式,就是1中我們所說網站A(客戶端)

(2)HTTP service:HTTP服務提供商,本文中簡稱"服務提供商",即1中我們所說的微博。

(3)Resource Owner:資源所有者,本文中又稱"使用者"(user)。

(4)User Agent:使用者代理,本文中就是指瀏覽器。

(5)Authorization server:認證伺服器,即服務提供商專門用來處理認證的伺服器。

(6)Resource server:資源伺服器,即服務提供商存放使用者生成的資源的伺服器。它與認證伺服器,可以是同一臺伺服器,也可以是不同的伺服器。

3.認證原理

基本思路:

(A)客戶端向用戶請求授權

(B)客戶端獲得授權

(C)客戶端帶著使用者的授權去請求認證伺服器

(D)客戶端從認證伺服器獲得認證token

(E)客戶端使用token去請求資源伺服器

(F)資源伺服器對客戶端開放資源

當前的OAuth2.0有三種認證方式:

(1)授權碼模式

(A)使用者訪問客戶端,使用者被客戶端重定向到認證伺服器

(B)使用者決定是否授權

(C)使用者授權後客戶端會獲得一個授權碼

(D)客戶端使用授權碼與一個重定向的uri再次請求認證伺服器

(E)認證伺服器給客戶端一個access token和refresh token

這樣,客戶端就可以憑藉接入token去資源伺服器獲取資源,然後根據重定向uri回到指定頁面

A中首次請求認證伺服器時客戶端申請認證的URI,包含以下引數:

  • response_type:表示授權型別,必選項,此處的值固定為"code"
  • client_id:表示客戶端的ID,必選項
  • 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

C中認證伺服器迴應客戶端的URI,包含以下引數:

  • code:表示授權碼,必選項。該碼的有效期應該很短,通常設為10分鐘,客戶端只能使用該碼一次,否則會被授權伺服器拒絕。該碼與客戶端ID和重定向URI,是一一對應關係。
  • state:如果客戶端的請求中包含這個引數,認證伺服器的迴應也必須一模一樣包含這個引數。

Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA
          &state=xyz


D中客戶端向認證伺服器申請令牌的HTTP請求,包含以下引數:
  • grant_type:表示使用的授權模式,必選項,此處的值固定為"authorization_code"。
  • code:表示上一步獲得的授權碼,必選項。
  • redirect_uri:表示重定向URI,必選項,且必須與A步驟中的該引數值保持一致。
  • client_id:表示客戶端ID,必選項。
Content-Type: application/x-www-form-urlencoded grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb E中認證伺服器傳送的HTTP回覆,包含以下引數:
  • access_token:表示訪問令牌,必選項。
  • token_type:表示令牌型別,該值大小寫不敏感,必選項,可以是bearer型別或mac型別。
  • expires_in:表示過期時間,單位為秒。如果省略該引數,必須其他方式設定過期時間。
  • refresh_token:表示更新令牌,用來獲取下一次的訪問令牌,可選項。
  • scope:表示許可權範圍,如果與客戶端申請的範圍一致,此項可省略。
Pragma: no-cache    { "access_token":"2YotnFZFEjr1zCsicMWpAA","token_type":"example","expires_in":3600,"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA","example_parameter":"example_value"} (2)簡化模式 (A)客戶端將使用者重定向到認證伺服器 (B)使用者決定是否授權 (C)使用者授權,則認證伺服器重定向客戶端一開始指定的uri,並帶上一個hash值的token (D)客戶端請求資源伺服器,並不帶上一步的hash值token (E)資源服務返回一個網頁程式碼可以提取hash值的原token (F)瀏覽器提取token (G)把token發給客戶端 A中客戶端發出的HTTP請求,包含以下引數:
  • response_type:表示授權型別,此處的值固定為"token",必選項。
  • client_id:表示客戶端的ID,必選項。
  • redirect_uri:表示重定向的URI,可選項。
  • scope:表示許可權範圍,可選項。
  • state:表示客戶端的當前狀態,可以指定任意值,認證伺服器會原封不動地返回這個值
GET /authorize?response_type=token&client_id=s6BhdRkqt3&state=xyz
        &redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1

C中認證伺服器迴應客戶端的URI,包含以下引數:
  • access_token:表示訪問令牌,必選項。
  • token_type:表示令牌型別,該值大小寫不敏感,必選項。
  • expires_in:表示過期時間,單位為秒。如果省略該引數,必須其他方式設定過期時間。
  • scope:表示許可權範圍,如果與客戶端申請的範圍一致,此項可省略。
  • state:如果客戶端的請求中包含這個引數,認證伺服器的迴應也必須一模一樣包含這個引數。
Location: http://example.com/cb#access_token=2YotnFZFEjr1zCsicMWpAA &state=xyz&token_type=example&expires_in=3600 (3)密碼模式 使用者向客戶端提供自己的使用者名稱和密碼。客戶端使用這些資訊,向"服務商提供商"索要授權。

在這種模式中,使用者必須把自己的密碼給客戶端,但是客戶端不得儲存密碼。通常只有使用者

對客戶端十分信任才會使用。

(A)使用者提供使用者名稱和密碼 (B)客戶端將其發給認證伺服器認證 (C)認證伺服器認證通過後向客戶端分發token B中客戶端發出的HTTP請求,包含以下引數:
  • grant_type:表示授權型別,此處的值固定為"password",必選項。
  • username:表示使用者名稱,必選項。
  • password:表示使用者的密碼,必選項。
  • scope:表示許可權範圍,可選項
Content-Type: application/x-www-form-urlencoded  grant_type=password&username=johndoe&password=A3ddj3w C中認證伺服器向客戶端傳送訪問令牌 Pragma: no-cache    {"access_token":"2YotnFZFEjr1zCsicMWpAA","token_type":"example","expires_in":3600,"refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA","example_parameter":"example_value"}

4.第三方登入demo(參照http://blog.csdn.net/woshihaiyong168/article/details/54862123)

實現流程:

  所需條件:

    1、一個線上的域名

    2、新浪微博開發者(自己去註冊)

 建立應用:


將下載的txt檔案扔進線下伺服器的根目錄下,點選驗證

將下圖中的的程式碼複製到一個html頁面中