登錄和第三方授權(Cookie和Authorization)

1 登錄和授權的區別

  • 登錄:身份認證,即確認[你是你]的過程。比如你輸入用戶名和密碼請求,向服務器確認[你是你]

  • 授權:由身份或持有的令牌確認享有某些權限(例如獲取用戶信息)【比如古代皇上有權利殺任何人,其他人要有權利殺人需要有尚方寶劍,皇上給我尚方寶劍是授權方,尚方寶劍就是一個令牌,我就是令牌的持有方】。

登錄過程實質上的目的也是爲了確認權限,直接把我的權限授予我自己,相比授權就少了令牌這個概念。

因此,在實際的應用中,多數場景下的[登錄]和[授權]界限是模糊的。

目前,登錄和授權有兩種方式:CookieAutorization,它們都是添加在header中的屬性。

2 Cookie

2.1 Cookie的工作機制

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

  • 服務器需要客戶端保存的內容,放在 set-cookie headers裏返回,客戶端會自動保存(客戶端會將服務器返回給我的 set-cookie 原封不動的保存,並且也會將訪問的 host 地址作爲鍵也存到cookie中,下次訪問同一個地址時就會攜帶存儲在客戶端的cookie一起發送請求)

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

  • 客戶端保存的cookies,會在之後的所有請求裏都攜帶進 cookie header裏發回給服務器

  • 客戶端保存cookie是按照服務器域名來分類的,例如 shop.com 發會的cookie保存下來以後,在之後向 games.com 的請求中並不會攜帶

  • 客戶端保存的cookie在超時後會被刪除、沒有設置超時時間的cookie(稱作 session cookie)在瀏覽器關閉後就會自動刪除;另外,服務器也可以主動刪除還未過期的客戶端cookies

簡單來說,客戶端只處理對cookie的保存,在訪問同一個服務器的時候將保存到本地的cookie給發過去就行了;cookie的計算和修改是有服務器處理。

cookie就是在客戶端幫助服務端記錄保存狀態的工作機制

cookie在移動端目前基本只處理登錄記錄,在往後的時間可能會慢慢的被拋棄。

2.2 Cookie的作用

  • 會話管理:登錄狀態、購物車等

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
爲什麼需要 sessionid

假如你輸入用戶名密碼登錄了賬戶,服務器記錄你已經登錄了,然後又有其他人請求服務器想查詢你的用戶信息,因爲請求是HTTP,HTTP是無狀態的,此時沒有 sessionid 服務器又查詢到你當前已經登錄了,然後就會處理請求結果返回信息。

沒有 sessionid 是不安全的,sessionid 能記錄哪個客戶端登錄了,客戶端通過在cookie攜帶 sessionid 讓服務器知道你是哪個客戶端,讓HTTP請求是有狀態的。

客戶端訪問同一個服務器可以存儲多個cookie,比如用戶登錄後存儲了服務器在cookie返回的 sessionid,然後向服務器發送其他請求也返回cookie。在這裏插入圖片描述

  • 個性化:用戶偏好、主題

比如客戶端請求了藍色主題,在下次訪問其他頁面時,服務器記錄了客戶端的主題就會給頁面提供藍色主題。

在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述

  • Tracking:分析用戶行爲

在這裏插入圖片描述

上面是客戶端訪問 shop.com 時展示一個html頁面。這個頁面有一個圖片 http://3rd-party.com/image.jpg,這張圖片由第三方 3rd-party.com 提供。

你在這個圖片的訪問被記錄了 from=shop.com 外鏈給第三方,這能讓第三方公司 3rd-party.com 知道你是在 shop.com 查看了這張圖片,第三方公司能跟蹤到你的行爲,並給你返回cookie讓客戶端保存。

下次你在其他網站展示圖片,而圖片同樣來自 3rd-party.com,你就會攜帶當時第三方給你的cookie,並且讓第三方再記錄你在哪個網站的訪問,第三方就會跟蹤完善對你的分析,推薦給你需要符合的信息。

2.3 Cookie存在的問題(瞭解即可)

  • XSS(Cross-site scripting):跨站腳本攻擊。即使用javascript拿到瀏覽器的cookie之後,發送到自己網站,以這種方式來盜取用戶cookie

應對方式:HttpOnly。這個cookie只能用於HTTP請求,不能被javascript調用。它可以防止本地代碼濫用cookie。客戶端在HTTP請求時在cookie加上這個屬性 Cookie:HttpOnly

  • XSRF(Cross-site request forgery):跨站請求僞造。即在用戶不知情的情況下訪問已經保存了cookie的網站,以此來越權操作用戶賬戶(例如盜取用戶資金)

應對方式:Referer校驗,主要從服務器安全角度考慮。

3 Authorization

Authorization 授權有兩種主流方式:

  • Basic

  • Bearer

3.1 Basic

Basic 用得比較少,但也是很有用。格式如下:

// HTTP header中添加
// 對username:password進行Base64作爲header的授權
Authorization:Basic<username:password(Base64ed)>

GET /user HTTP/1.1
Host:xxx.com
Authorization:Basic xxxx

雖然Basic簡單,但是有風險(不過是可避免的):

  • 使用的Base64(Base64是可逆的解碼的),但是這可以通過HTTPS來解決,不完全是Basic的問題

  • token需要反覆使用,那就要存在本地文件,如果手機被root了,有些惡意軟件僞裝成工具軟件就有可能把token竊走,只能改密碼

3.2 Bearer

Bearer 的授權流程還是要從OAuth2流程來說明。

格式如下:

// HTTP header中添加
Authrization:Bearer<barer token>

3.2.1 OAuth2流程(第三方授權)

OAuth2授權操作流程(以掘金申請授權github賬戶爲例子,第三方網站:掘金,授權方網站:github):

  • 第三方網站向授權方網站申請第三方授權合作,拿到 client idclient secret

在這裏插入圖片描述

  • 用戶在使用第三方網站時,點擊授權按鈕[通過github授權],第三方網站將頁面跳轉到授權方網站,並傳入 client id 作爲自己的身份標識
    在這裏插入圖片描述
    在這裏插入圖片描述
  • 授權方網站根據 client id,將第三方網站的信息和第三方網站需要的用戶權限展示給用戶,並詢問用戶是否同意授權
    在這裏插入圖片描述
  • 用戶點擊[同意授權]按鈕後,授權方網站將頁面跳轉回第三方網站,並傳入 Authorization code 作爲用戶認可的憑證
    在這裏插入圖片描述
  • 第三方網站將 Authorization code 發送回自己的服務器
    在這裏插入圖片描述
  • 服務器將 Authorization code 和自己的 client secret 一併發送給授權方的服務器,授權方服務器在驗證通過後,返回 access token。OAuth流程結束
    在這裏插入圖片描述
// HTTP請求帶上access token從github獲取用戶信息處理註冊登錄
GET /user HTTP/1.1
Host: github.com
Authorization: Bearer xxxx
  • 在上面的過程結束之後,第三方網站的服務器(或者有時客戶端也會)就可以使用 access token 作爲用戶授權的令牌,向授權方網站發送請求來獲取用戶信息或操作用戶賬戶。但這已經在OAuth流程之外

爲什麼用戶點擊授權按鈕時要先拿到 Authorization code,然後把 Authorization code 發送給服務器後,再通過 Authorization code 獲取到 access token,而不是用戶點擊授權按鈕後直接返回 access token

其實是爲了安全,Authorization code 不是token,而是用來獲取token的。OAuth不強制授權流程必須使用HTTPS,通過 Authorization code 授權方github能判斷是哪個第三方跟它獲取 access token。因此需要保證當通信路徑中存在竊聽者時,依然具有足夠高的安全性。

3.2.2 微信登錄(第三方登錄)

在這裏插入圖片描述

第三方App微信登錄其實也是一個OAuth2流程:

  • 第三方App向騰訊申請第三方授權合作,拿到 client idclient secret

  • 用戶在使用第三方App時,點擊[微信登錄],第三方App將使用微信sdk跳轉到微信,並傳入自己的 client id 作爲自己的身份標識

  • 微信通過和服務器交互,拿到第三方App的信息,並限制在界面中,然後詢問用戶是否同意該App使用微信登錄

  • 用戶點擊[使用微信登錄]後,微信和服務器交互將授權信息提交,然後跳轉回第三方App,並傳入 Authorization code 作爲用戶認可的憑證

  • 第三方App調用自己服務器的[微信登錄]API,並傳入 Authorization code,然後等待服務器響應

  • 服務器在收到登錄請求後,拿收到的 Authorization code 去向微信的第三方授權接口發送請求,將 Authorization code 和自己的 client secret 一起作爲參數發送,微信在驗證通過後,返回 access token

  • 服務器在收到 access token 後,立即拿着 access token 去向微信的用戶信息接口發送請求,微信驗證通過後,返回用戶信息

  • 服務器在收到用戶信息後,在自己的數據庫中爲用戶創建一個賬戶,並使用從微信服務器拿來的用戶信息填入自己的數據庫,以及將用戶的ID和用戶的微信ID做關聯

  • 用戶創建完成後,服務器向客戶端的請求發送響應,傳送會剛創建好的用戶信息

  • 客戶端收到服務器響應,用戶登錄成功

上面是第三方App微信登錄的流程。

在實際開發中,發現了一種錯誤的做法,服務器在拿到 access token 後,就把 access token 發給客戶端,讓客戶端自己去授權方獲取用戶數據。這就把OAuth2的優勢浪費了,Authorization code 就沒用了,這樣還是會泄露 access token這是錯誤的
在這裏插入圖片描述在這裏插入圖片描述

3.2.3 OAuth2流程簡單總結

OAuth2流程簡單說明:

  • 1、第三方網站持有授權網站給的 client idclient secret

  • 2、用戶在第三方網站授權登錄,跳轉到授權網站提供 client id

  • 3、用戶允許授權拿到 Authrization code 給第三方網站服務器

  • 4、第三方網站服務器把 Authrization codeclient secret 給授權網站拿到 access token

上面的流程客戶端只需要做第2、3步即可,剩下的都是服務器處理。

上面雖然列出了第三方授權和第三方登錄,但是要區分好兩者:

在技術上,其實只有第三方授權,沒有第三方登錄。因爲第三方登錄是github授予權限給掘金,掘金就可以通過token拿到github的用戶信息,通過這些信息在掘金自己的服務器處理註冊登錄賬號。

第三方登錄是基於第三方授權的,所以掘金在登錄過程中它不是第三方,因爲它是實際給你註冊登錄的;而在授權過程中它是第三方,因爲它是被github授權的。

3.2.4 自家App中使用Bearer token

有的App會在API設計中,將登錄和授權設計成類似OAuth2的流程,但簡化掉 Authrization code 概念。即:登錄接口請求成功時,會返回 access token,然後客戶端在之後的請求中,就可以使用這個 access token 來當作 bearer token 進行用戶操作了。

3.2.5 Refresh token

{
	"token_type": "Bearer"
	"access_token": "xxxxx"
	"refresh_token": "xxxxx"
	"expires_time": "xxxxx"
}

access_token 有失效時間,在它失效後,調用 refresh_token 接口,傳入 refresh_token 來獲取新的 access_token

提供 refresh token 主要是爲了安全,可以做到以下處理:

  • access token 失竊,由於它有失效時間,因此壞人只有較短的時間來[做壞事]

  • 由於(在標準的OAuth2流程中)refresh token 永遠只存在於第三方服務的服務器中,因此 refresh token 幾乎沒有失竊的風險

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章