談談前後端分離及認證選擇

DeanWu發表於2020-09-24

前幾年,web開發領域中「前後端分離」比較火,現如今已逐漸成為事實標準。但是究竟什麼是前後端分離?又為什麼要前後端分離呢?

什麼是前後端分離?為什麼要前後端分離?

前後端分離,說的更多的是一種架構上的概念。在傳統的web架構中,比如經典的MVC,會分資料層、邏輯層、檢視層。這個檢視層即我們所說的前端了,對映到程式碼層面,就是html、js、css等程式碼檔案。資料層和邏輯層更多的是後端部分,例如我們的 .java.go.py等檔案。這些檔案會在一個工程中,並不會單獨的開發、測試、部署。

在前後端分離的架構中,前端和後端是分開的,分別在不同的工程中。前端有專門的前端開發人員來進行開發、測試,後端則有後端開發人員來進行開發、測試,他們之間通過API來互動。

前後端分離有這麼幾個好處:

1/ 解耦了前後端的工作人員 讓前端和後端分別交給更擅長的人來做,細化了工種,可以更加的專精。前端人員來關心使用者體驗、UI設計、互動渲染;後端人員更關注業務邏輯、效能保障、安全等方面。在專案進度方面,前後端可以並行開發,而互不影響,加快了整體的專案進度。

2/ 解耦了前後端的程式碼 後端只需提供API服務,不再與靜態檔案互動。後端可以使用更復雜的分散式、微服務架構,提供更好的效能和穩定性保障。同時前端除了PC端之外,移動端也可以使用相同的一套後端服務。

看到這裡,前後端分離被廣泛應用也可以理解了。

大家需要注意,並不是所有的專案都需要前後端分離,像是大型的專案,開發人員很多,人員分工明確,這種團隊配置下,使用前後端分離可增加工作效率提高系統質量。但是團隊人員少,分工不那麼明確的情況下,再採用前後端分離的架構,只會增加開發成本和系統複雜度。前後端分離是一個好的架構思路,但是需要看具體的業務和人員情況,切勿盲目的跟從。

前後端分離常用的認證方式

前後端分離中前後端的互動是通過API進行的,那麼其中的認證是少不了的。前後端分離中常用的認證方式有下面幾種:

  • Session-Cookie
  • Token 驗證
  • OAuth(開放授權)

Session-Cookie 方式

Session-Cookie 方式是我們開發web應用時最常用的認證方式。它的認證過程一般是這樣的:

  • 1/ 使用者瀏覽器向伺服器發起認證請求,將使用者名稱和密碼傳送給伺服器。
  • 2/ 伺服器認證使用者名稱和密碼,若通過則建立一個session對話,並將使用者資訊儲存到session中。session的資訊可以是儲存到伺服器檔案、共享外部儲存、資料庫等儲存中,等下次請求時查詢驗證使用。
  • 3/ 伺服器會將該session的唯一標識ID,返回給使用者瀏覽器,並儲存在cookie中。
  • 4/ 使用者請求其他頁面時,瀏覽器會自動將使用者的cookie攜帶上,併發起介面請求,服務端收到請求後,從cookie解析出sessionID, 根據這個sessionID 查詢登入後並儲存好的session,若有則說明使用者已登入,放行。

該方式是MVC架構中最常用的認證方案,在前後端分離中也是可以用的。幾乎所有的Web框架都預設整合了Session-Cookie的認證方式,而且對Session-Cookie方式的安全性和穩定性方面都有很成熟的處理方案。

當前端程式碼使用後端web框架當做web容器驅動時,Session-Cookie 方案可作為首選的認證方案。

Token 方式

Token 方式是不同系統互動、前後端架構常用的認證方式。Token 方式的認證流程如下:

  • 1/ 使用者使用使用者名稱和密碼登入,將使用者名稱和密碼傳送給伺服器。
  • 2/ 伺服器驗證使用者名稱和密碼,若正確,則簽發token,返回給使用者。
  • 3/ 使用者收到token後,將其儲存起來,web服務一般為localStrage 或cookie。
  • 4/ 使用者請求其他資源頁面時,會攜帶token,一般放到header 或引數中,傳送給服務端。
  • 5/ 伺服器收到後,驗證token,判斷使用者的正確性。

JWT(JSON Web Token)是最常用的一種Token認證方式,已成為Token認證的標準事實。JWT 方式將Token 分段,使其可以保持少量資料,還增加了簽名驗證,確保了token的安全性。JWT 網上介紹的資料很多,這裡不再贅述。不瞭解的,可參考下邊這些資料:

OAuth 方式

OAuth(Open Authorization)是一個開放標準,允許使用者授權第三方網站訪問他們儲存在服務端的使用者資訊。我們常見的的QQ、微信等第三方登入便是Auth認證方式。OAuth協議有1.0和2.0兩個版本。相比較1.0版,2.0版整個授權驗證流程更簡單更安全,也是目前最主要的使用者身份驗證和授權方式。

OAuth更像是一種授權機制。資料的所有者告訴系統,同意授權第三方應用進入系統,獲取這些資料。系統從而產生一個短期的進入令牌(token),用來代替密碼,供第三方應用使用。

在單純的前後端分離系統中,OAuth並不是常用的方式,它更多的應用在不同系統之間的授權互動。

對比思考

刨去不常用的OAuth,這裡對比兩種前兩種常用的認證方式 JWT Auth 和 Session-Cookie Auth ,到底誰才是前後端分離認證的最佳實踐呢。從下面幾個方向分析比對。

可擴充套件性

Session-Cookie 是有狀態的服務,在服務端儲存了session的資訊。當服務端擴容的時候,需要考慮到session的共享問題,這個問題已有成熟的解決放方案,可使用session複製、共享、持久化等方式解決,大多數的分散式Web框架已經整合了處理方案。JWT 驗證方式是無狀態的服務,服務端可隨意擴縮容。

Session-Cookie 方式基於Cookie,也就是必須是瀏覽器或支援Cookie的瀏覽器封裝的框架,純移動端無法使用。JWT 不同,不依賴Cookie, 只要在本地可儲存即可。

安全性

Web開發中常見的兩個安全問題 XSS(跨站點指令碼攻擊) 和 CRSF (跨站點請求偽造)。前者利用注入指令碼到使用者認證網站上,執行惡意指令碼程式碼。後者則利用瀏覽器訪問後端自動攜帶cookie的機制,來跨站偽造請求。XSS 只要我們對注入端,進行過濾、轉義就能解決,CRSF 是我們重點關注的。

在Session-Cookie認證方式中,因為把SessionID儲存在了Cookie中,很容易引起CRSF攻擊。在大多數的WEB框架中有整合解決方案,如Django 的csrftoken 、Beego的xsrfToken 等。在使用Session-Cookie方案時建議開啟web框架的csrf功能。

JWT 認證,可以把Token存放在Cookie或localstorage。建議存在localstorage,這樣就徹底避免了 CRSF 攻擊。

另外JWT有幾個安全性的問題,需要注意:

  • 1/ JWT是明文編碼 JWT 的編碼是明文Base64的一個編碼,是可以反編譯的。在使用JWT傳輸資訊的時候,不要放置重要敏感資訊,最好使用https。
  • 2/ JWT 洩露問題 解決JWT的洩露問題是一個平衡的問題。有三種處理方式由輕到重,看你業務重要性酌情選擇:

    • 將JWT 的過期時間設定的很短,即使洩露也無關緊要。
    • 在服務端設計JWT的黑名單機制,將洩露的Token 加黑名單即可。
    • 儲存簽發的JWT,當JWT洩露時,直接設定失效。

效能

Session-Cookie方案,因為後端服務儲存了Session資訊,在認證的時候需要查詢,當有大量認證的時候是非常耗費資源的。JWT 可以把資訊放到token中,只需要驗證解碼,使用簽名驗證token即可,相對來說效率會有提升。

從上面三個方面,我們分析了Session-Cookie和JWT 方式各自的優缺點,和麵對問題的一些應對方案。相信大家會有自己的心裡選擇。

拋開業務場景談技術都是耍流氓。不同的業務場景,不同的架構設計,適用的認證方式也是不同的。這裡按我自己的經驗總結了下,什麼情況下該使用那種認證方式,大家可參考。

適用Session-Cookie認證方案的情況:

  • 專案只有web端的情況;
  • 專案人員配置少,且前後端開發都會參與;
  • 專案前後端分離不徹底,前端使用後端web框架作為服務容器啟動;

使用 JWT 認證方案的情況:

  • 專案人員配置充足,分工明確;
  • 專案除web端外還有移動端;
  • 臨時的授權需求;
  • 純後端系統之間的互動。

本文圍繞前後端分離這個話題總結分享了前後端分離時的認證方案。這些僅僅是通用的一般方案,在具體的業務場景中,還有很多不典型的擴充套件的驗證方案也是極好的,歡迎大家留言討論自己心中的最佳認證方案。

參考及擴充套件閱讀

相關文章