前端應該知道的web登入

亞古發表於2019-04-27
還記得在上家公司做全乾工程師的時候,基本從頁面寫到運維,當時做登入這塊的時候,被session、cookie、token各種概念差點整蒙圈了,上網查詢相關概念,發現很多人都是類似的疑惑,比如:

前端應該知道的web登入

前端應該知道的web登入前端應該知道的web登入

前端應該知道的web登入

來了位元組跳動之後,前端很少接觸HTTP請求之後的事情,而且登入相關的SDK封裝的很好,所以這篇文章就簡單的學習記錄一下。

為什麼會有登入這回事

首先這是因為HTTP是無狀態的協議,所謂無狀態就是在兩次請求之間伺服器並不會儲存任何的資料,相當於你和一個人說一句話之後他就把你忘掉了。所以,登入就是用某種方法讓伺服器在多次請求之間能夠識別出你,而不是每次發請求都得帶上使用者名稱密碼這樣的識別身份的資訊。 從登入成功到登出的這個過程,伺服器一直維護了一個可以識別出使用者資訊的資料結構,廣義上來說,這個過程就叫做session,也就是保持了一個會話。

常見的兩種登入

忽然想到一點,看了網上很多問題,我覺得大家應該區分兩個概念:廣義的session狹義的session

廣義的session:廣義的session就是從登入成功到登出的過程,在這個過程中客戶端和伺服器端維持了保持登入的狀態,至於具體怎麼維持住這種登入的狀態,沒有要求。
狹義的session:狹義的session就是登入成功後,伺服器端儲存了一些必須的使用者資訊,這部分存在伺服器端的使用者資訊就叫做session,也就是接下來要說的第一種登入的實現方式。

伺服器session+客戶端sessionId

先用圖來看:

前端應該知道的web登入

詳細說的說一下,這裡面主要是這麼幾個過程:

  1. 客戶端帶著使用者名稱和密碼去訪問 /login 介面,伺服器端收到後校驗使用者名稱和密碼,校驗正確就會在伺服器端儲存一個sessionId和session的對映關係前端應該知道的web登入


  2. 伺服器端返回response,並且將sessionId以set-cookie的方式種在客戶端,這樣一來,sessionId就存在了客戶端。這裡要注意的是,將sessionId存在cookie並不是一種強制的方案,而是大家一般都這麼做,而且發請求的時候符合domain和path的時候,會自動帶上cookie,省去了手動塞的過程。
  3.  客戶端發起非登入請求時,服務端通過cookie中的sessionId找到對應的session來知道此次請求是誰發出的。

token

前面說到sessionId的方式本質是把使用者狀態資訊維護在server端,token的方式就是把使用者的狀態資訊加密成一串token傳給前端,然後每次發請求時把token帶上,傳回給伺服器端;伺服器端收到請求之後,解析token並且驗證相關資訊;


所以跟第一種登入方式最本質的區別是:通過解析token的計算時間換取了session的儲存空間

業界通用的加密方式是jwt(json web token),jwt的具體格式如圖:

前端應該知道的web登入

簡單的介紹一下jwt,它主要由3部分組成:

header 頭部
{
  "alg": "HS256",
  "typ": "JWT"
}
payload 負載
{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1555341649998
}
signature 簽名複製程式碼
header裡面描述加密演算法和token的型別,型別一般都是JWT;
payload裡面放的是使用者的資訊,也就是第一種登入方式中需要維護在伺服器端session中的資訊;
signature是對前兩部分的簽名,也可以理解為加密;實現需要一個金鑰(secret),這個secret只有伺服器才知道,然後使用header裡面的演算法按照如下方法來加密:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)複製程式碼
總之,最後的 jwt = base64url(header) + "." + base64url(payload) + "." + signature


jwt可以放在response中返回,也可以放在cookie中返回,這都是具體的返回方式,並不重要。
客戶端發起請求時,官方推薦放在HTTP header中:

Authorization: Bearer <token>複製程式碼

這樣子確實也可以解決cookie跨域的問題,不過具體放在哪兒還是根據業務場景來定,並沒有一定之規。

兩種登入方案存在的問題

session方式

  1. session方式由於會在伺服器端維護session資訊,單機還好說,如果是多機的話,伺服器之間需要同步session資訊,服務橫向擴充套件不方便。
  2. session數量隨著登入使用者的增多而增多,儲存會增加很多。
  3. session+cookie裡面存sessionId的方式可能會有csrf攻擊的問題,常見的方式是使用csrf_token來解決

jwt方式

  1. jwt的過期時間需要結合業務做設定,而且jwt一旦派發出去,後端無法強行使其作廢

後話

理清概念,一身輕鬆


相關文章