實現登錄狀態保持的方法
方法一:cookie和session配合使用
首先,用戶登錄輸入用戶名和密碼,瀏覽器發送post請求,服務器後臺獲取用戶信息,查詢數據庫驗證用戶信息是否正確。如果驗證通過,就會創建session來存儲相關信息,並且生成一個cookie字符串,把sessionID放在cookie裏面。然後返回給瀏覽器。
當用戶下一次發起請求時,瀏覽器會自動攜帶cookie去請求服務器,服務器識別後,通過裏面的sessionID,就可以直接讀取session中的用戶信息。這樣,用戶就可以直接訪問,不需要再輸入用戶名和密碼來驗證身份。
缺點:
cookie
容易被修改,被劫持,並不是絕對的安全- 大型項目中,服務器往往不止一臺
如果第一次請求,用戶信息被保存在服務器1的session
空間裏。而第二次請求被分流到了服務器2,這樣就獲取不到用戶信息,依然要重新登錄。
方法二:如果cookie被禁用了,怎麼保持登錄狀態?
保持登錄的關鍵不是cookie
,而是通過 cookie
保存和傳輸的 sessionID
,其本質是能獲取用戶信息的數據。除了 cookie
,還通常使用 HTTP
請求頭來傳輸,比如標準的Authorization
,也可以自定義,如 X-Auth-SessionID
等。但是這個請求頭瀏覽器不會像 cookie
一樣自動攜帶,需要手工處理。也可以進行url
地址重寫,將sessionID
追加在url
後面
注意:
前面的cookie
和session
這種模式,沒有分佈式架構,無法支持橫向擴展。如果使用一個服務器,該模式完全沒有問題。但是,如果它是服務器羣集或面向服務的跨域體系結構的話,則需要一個統一的session
數據庫來保存會話數據實現共享,這樣負載均衡下的每個服務器纔可以正確的驗證用戶身份。
方法三:Token
Token
是在服務端產生的。如果前端使用用戶名/密碼向服務端請求認證,服務端認證成功,那麼在服務端會返回Token
給前端。前端可以在每次請求的時候帶上 Toke
證明自己的合法地位。如果這個Token
在服務端持久化(比如存入數據庫),那它就是一個永久的身份令牌。
方法四:JWT(JSON Web Token)
什麼是JWT?
JSON Web Token(JWT)
是一個開放式標準(RFC 7519),它定義了一種緊湊且自包含的方式,用於在各方之間以JSON
對象安全傳輸信息。這些信息可以通過數字簽名進行驗證和信任。可以使用祕鑰(使用HMAC
算法)或使用RSA
的公鑰/私鑰對對JWT
進行簽名。
爲什麼使用JWT?
隨着技術的發展,分佈式web
應用的普及,通過session
管理用戶登錄狀態成本越來越高,因此慢慢發展成爲token
的方式做登錄身份校驗,然後通過token
去取redis
中的緩存的用戶信息。隨着之後JWT
的出現,校驗方式更加簡單便捷化,無需通過redis
緩存,而是直接根據token
取出保存的用戶信息,以及對token
可用性校驗,單點登錄更爲簡單。
JWT的優點:
- 體積小,因而傳輸速度更快
- 多樣化的傳輸方式,可以通過
URL
傳輸、POST
傳輸、請求頭Header
傳輸(常用) - 簡單方便,服務端拿到
jwt
後無需再次查詢數據庫校驗token
可用性,也無需進行redis
緩存校驗 - 在分佈式系統中,很好地解決了單點登錄問題
- 很方便的解決了跨域授權問題,因爲跨域無法共享
cookie
JWT的缺點:
- 因爲
JWT
是無狀態的,因此服務端無法控制已經生成的Token
失效,這是不可控的 - 獲取到
JWT
也就擁有了登錄權限,因此JWT
是不可泄露的,網站最好使用https
,防止中間攻擊偷取JWT
實現方式:
JWT
的原則是在服務器身份驗證之後,將生成一個JSON
對象並將其發送回用戶;- 之後,當用戶與服務器通信時,客戶端在請求中發回
JSON
對象。服務器僅依賴於這個JSON
對象來標識用戶。爲了防止用戶篡改數據,服務器將在生成對象時添加簽名 - 服務器不保存任何會話數據,即服務器變爲無狀態,使其更容易擴展。
Token和JWT的區別
相同:
- 都是訪問資源的令牌, 都可以記錄用戶信息
不同:
- 服務端驗證客戶端發來的
token
信息要進行數據的查詢操作 JWT
驗證客戶端發來的token
信息就不用, 在服務端使用密鑰校驗就可以,不用數據庫的查詢。
cookie和token都存放在header中,爲什麼不會劫持token?
token
不是爲了防止XSS
的,而是爲了防止CSRF
的;CSRF
攻擊的原因是瀏覽器會自動帶上cookie
,而不會帶上token
;
CSRF
就是利用的這一特性,所以token
可以防範CSRF
,而cookie
不能。JWT
本身只關心請求的安全性,並不關心token
本身的安全。