幾種常見的身份認證方案和介面測試中的應用

星海后台测试平台發表於2020-10-15

寫在前面

最近做了幾個專案的介面測試接入工作,主要是結合星海後臺測試平臺(內部的統一介面測試平臺)完成各個專案基礎框架的搭建,並結合專案實際情況使用普通模式編寫用例(透過網頁編輯,填空式)和高階模式(直接編寫程式碼),來提升介面測試的整體效率。

身份認證

幾乎所有專案遇到的首個問題就是身份認證。因為大部分介面都不允許、也不應該匿名使用,所以一般都會透過 HTTP Header 或 URL 中的 Query String 攜帶一個令牌(token),來表明使用者身份。

一般來講,token 如果根據有效期來分類的話,有永久有效(當然可以後臺手動吊銷)和一定時間內有效兩類。根據許可權又可以分為完全許可權和指定作用閾。根據專案實際情況,可能還有更多的劃分。

一個典型的認證流程:

  1. 使用者向伺服器傳送使用者名稱和密碼。

  2. 伺服器驗證透過後,在當前對話(session)裡面儲存相關資料,比如使用者角色、登入時間等等。

3.伺服器向使用者返回一個 session_id,寫入使用者的 Cookie。

4.使用者隨後的每一次請求,都會透過 Cookie,將 session_id 傳回伺服器。

5.伺服器收到 session_id,找到前期儲存的資料,由此得知使用者的身份。

這種模式的問題在於,擴充套件性(scaling)不好。單機當然沒有問題,如果是伺服器叢集,或者是跨域的服務導向架構,就要求 session 資料共享,每臺伺服器都能夠讀取 session。
所以,後來又有了 JWT(JSON Web Token) 方案。詳細的原理和用法這裡就不展開了,可以讀一下阮一峰的《JSON Web Token 入門教程》,或 Auth0 出品的《JWT Handbook》。
另外,前面提到的典型認證流程,第一步是透過使用者名稱和密碼認證。但是對於第三方服務(例如餓了麼之於微信),還會用到 OAuth2.0 的標準。簡單描述就是,使用者點選 “同意” 授權,由微信和餓了麼在後臺完成鑑權,最後頒發一個短期有效的令牌。具體的原理也可以透過阮一峰的《理解 OAuth 2.0》瞭解。

身份認證與介面測試

介面測試的設計中,獨立性是一個十分重要的原則。這就要求我們編寫的每條測試用例是可以獨立執行、互不影響的。並且很多時候為了提高效率,介面測試都是併發執行。這樣一來,每個用例如果都先完成身份認證流程,再走正常邏輯,這樣給身份認證介面帶來很多不必要的壓力。另一方面,如果後臺一般會對此介面進行頻率限制(防止暴力破解),則會導致測試失敗。

所以,為了解決這個問題,我們需要引入一個外部服務,來完成 “統一認證” 流程。

併發的情況下,要保證 token 有效,方案相對複雜,詳細的討論可以看這篇帖子:《高併發如何保證微信 access_token 的有效》。

騰訊雲實戰

前面提到了併發情況下 token 有效性的問題,《高併發如何保證微信 access_token 的有效》文中對單程序、多程序等場景提供了多種方案。雖然照做可以解決問題,但是還需要獨立的伺服器部署和維護,對於我們來說成本太高。騰訊雲提供了無伺服器雲函式(Serverless Cloud Function,SCF)、API 閘道器(API Gateway)和物件儲存(COS)三種產品,並且都有非常大的免費額度,我們幾乎不用為此付費即可搭建一個穩定的統一身份認證服務。

所以我們的具體方案可以最佳化為:

統一登入服務定時(假設一般 token 2 小時過期,我們每個小時去請求一次)去後臺請求新的 token,並將其序列化儲存到 COS ;對於舊的 token,每次請求新 token 時驗證其有效期,如果有效期不足(例如小於 5 分鐘)則從 COS 中刪除。

具體使用 token 時,直接去 COS 中獲取即可,本地驗證有效性後使用。

下面簡述一下開發流程:

首先,在 COS 中建立一個 Bucket,用於資料持久化(也可以用資料庫代替)。
在 SCF 中建立函式服務,選擇一門你熟悉的語言環境,編寫核心程式碼,並進行測試。完成後,新增觸發方式為定時觸發(即定時重新整理 token)
在 API Gateway 中,建立介面。其中,後端使用 cloud function,然後選擇上一步建立的函式。
測試環境進行測試,沒問題後釋出到正式環境。如果有需要,還可以繫結自定義域名。
需要注意:

因為是把服務釋出到了外網,所以一定要注意安全問題。可以查詢相關文件的最佳實踐,有詳細說明

COS 中建議儲存多個有效的 token,本地使用時先驗證有足夠的有效期(防止 case 執行過程中過期)再使用

如果是 token 是 JWT 形式的,可以直接解析出過期時間等資料;如果是其他格式,需要自己維護一個欄位用來儲存有效期等屬性

對於類似 OAuth2.0 這種需要外部授權的服務,簡單的可以直接實現,複雜的(如微信)藉助手機自動化來實現。

寫在最後

十分感謝 Edsion 同學的分享,轉自 Edsion 同學的部落格 https://blog.i1hao.com/2018/10/08/oauth-and-api-test/

相關文章