還記得在上家公司作全乾工程師的時候,基本從頁面寫到運維,當時作登陸這塊的時候,被session、cookie、token各類概念差點整蒙圈了,上網查詢相關概念,發現不少人都是相似的疑惑,好比:html
來了字節跳動以後,前端不多接觸HTTP請求以後的事情,並且登陸相關的SDK封裝的很好,因此這篇文章就簡單的學習記錄一下。前端
首先這是由於HTTP是無狀態的協議,所謂無狀態就是在兩次請求之間服務器並不會保存任何的數據,至關於你和一我的說一句話以後他就把你忘掉了。因此,登陸就是用某種方法讓服務器在屢次請求之間可以識別出你,而不是每次發請求都得帶上用戶名密碼這樣的識別身份的信息。 從登陸成功到登出的這個過程,服務器一直維護了一個能夠識別出用戶信息的數據結構,廣義上來講,這個過程就叫作session,也就是保持了一個會話。web
突然想到一點,看了網上不少問題,我以爲你們應該區分兩個概念:廣義的session和狹義的session 算法
廣義的session:廣義的session就是從登陸成功到登出的過程,在這個過程當中客戶端和服務器端維持了保持登陸的狀態,至於具體怎麼維持住這種登陸的狀態,沒有要求。json
狹義的session:狹義的session就是登陸成功後,服務器端存儲了一些必須的用戶信息,這部分存在服務器端的用戶信息就叫作session,也就是接下來要說的第一種登陸的實現方式。後端
先用圖來看: 跨域
詳細說的說一下,這裏面主要是這麼幾個過程:服務器
前面說到sessionId的方式本質是把用戶狀態信息維護在server端,token的方式就是把用戶的狀態信息加密成一串token傳給前端,而後每次發請求時把token帶上,傳回給服務器端;服務器端收到請求以後,解析token而且驗證相關信息;cookie
因此跟第一種登陸方式最本質的區別是:經過解析token的計算時間換取了session的存儲空間session
業界通用的加密方式是jwt(json web token),jwt的具體格式如圖:
簡單的介紹一下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跨域的問題,不過具體放在哪兒仍是根據業務場景來定,並無必定之規。
理清概念,一身輕鬆
--------------------------------------------
歡迎關注個人公衆號,前端亞古獸,作前端,不止於作前端。