1. 程式人生 > >JWT: 基於Token的驗證

JWT: 基於Token的驗證

現在SPA(Single Page Application, 單頁面應用)和前後端分離已經是主流. 基於Token的驗證非常適合這種構架.

Difference between Token-based Auth and Cookie-based Auth

基於Cookie的驗證

基於Cookie的驗證是有狀態的 (stateful). 前後端都要為驗證儲存狀態: 後端要儲存active session的資訊, 前端要用cookie儲存sessionId. 流程如下:

  1. 使用者輸入登入資訊
  2. 伺服器驗證後, 建立session並儲存到資料庫
  3. 帶著sessionId的cookie儲存到瀏覽器中
  4. 接下來的所有請求, 後臺通過cookie攜帶的sessionId以找到對應的session.
  5. 使用者登出時, 前後端都要銷燬session

基於Token的驗證

近些年SPA, web API, 和IoT(Internet of Things, 物聯網)的崛起帶動了基於Token的驗證, 通常就是指JWT(Json Web Token)

JWT是無狀態的(stateless), 後端不必儲存有關session的資訊. 後端只需要驗證每次請求中攜帶的Token即可驗證請求的真實性.

Token通常以Bearer {JWT}的形式儲存在Authentication header中, 也可以放到POST body或query parameter中.

流程如下:

  1. 使用者輸入登入資訊
  2. 伺服器驗證後, 返回一個簽名(signed)的token. 該token儲存在前端, 通常在localStorage中, sessionStorage或cookie也可以.
  3. 接下來的請求中token被加到Authentication Header中, 或者POST body / query parameter中.
  4. 後臺解碼JWT, 若token合法, 則處理請求
  5. 使用者登出後, token從前端銷燬, 無需與後端互動.

基於Token的驗證的優勢

無狀態, 可擴充套件, 解耦合

基於Token的驗證是無狀態的, 後端無需儲存狀態. 每個token自己都儲存了足夠的驗證所需要的資訊.

後臺的任務只剩下對token簽名和驗證token兩項. 如果使用auth0之類的第三方服務進行token簽名, 後臺則只需要驗證token.

跨域問題

Cookie適用於單域名或者子域名的情況, 但是跨域的話就麻煩了. 基於Token的驗證則不關心域名.

在JWT中儲存資料

使用Cookie時, 你只儲存一個sessionId. 但是你可以在Token中儲存一些別的元資料. JWT文件中規定了一些預留/共有/私有的claim(宣告, 即JWT的欄位). 這意味著你可以在JWT中儲存諸如userId, expiration, email, permission之類的資訊.

效能

基於Cookie的驗證需要依賴資料庫儲存session資訊, 查詢資料庫往往比驗證token要耗時得多. 而且JWT允許你儲存一些常用資訊, 比如使用者許可權, 這樣又省去一些資料庫查詢開銷.

移動裝置

原生平臺上, cookie的使用會遇到一些問題/限制. 但是Token在iOS或者Android上實現都非常簡單. 對IoT裝置這種沒有cookie store概念的終端, Token更是最佳選擇.

常見問題

JWT大小

JWT最大的問題是大小. 最小的JWT也比儲存sessionId的cookie要大. 因此不要向JWT中加入太多claim.

JWT的儲存

最常見的是儲存在localStorage中. 但是localStorage中的資料無法被另一個域名或者子域名訪問.

存在cookie中的一個問題是, cookie的最大尺寸是4kb, 你無法儲存很多claim.

存在sessionStorage的話, 一旦使用者關閉瀏覽器, 登入資訊就被清空了.

XSS和XSRF攻擊

要注意Cross Site Scripting (XSS)和Cross Site Request Forgery (XSRF or CSRF)兩種攻擊.

XSS攻擊發生在當用戶可以在你的網站/app執行自己的程式碼的時候. 常見情況就是你不對使用者輸入進行清理, 導致使用者輸入的惡意程式碼被執行. Angular等常見的框架會自動清理使用者輸入, 阻止使用者程式碼的執行. 如果你沒用具有這類功能的框架, 你可以選擇一些外掛比如caja.

對於XSRF攻擊, 如果你用localStorage就不用擔心. 但是如果你用cookie的話, 就要防範這類攻擊. XSRF的攻擊方式和解決方法見這裡.

讓token有較短的過期時間, 可以確保當token被偷時, 它沒多久就會失效. 另外你可以維護一個被盜token的黑名單. 最後, 終極大招就是修改簽名演算法, 這樣所有的token都會失效, 所有使用者都要重新登入. 這是非正常時期的手段, 輕易勿用.

Token會被編碼, 但不會被加密

Token中的header和payload是base64url編碼的(注意不是base64), 它本身是用HMACSHA256演算法進行簽名的. 這意味著, 你儲存在payload中的資訊是公開的, 非加密的. 所以絕不要在token中儲存密碼之類的隱私資訊.

如果你非要儲存隱私資訊, 可以使用JWE(JSON Web Encryption), 它讓token無法被除了伺服器以外的所有人解讀. JOSE提供了一個很好的JWE框架, 還有對很多流行框架如NodeJSJava的SDK.

參考



作者:柳正來
連結:https://www.jianshu.com/p/000f5896d6fd
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

相關推薦

JWT: 基於Token驗證

現在SPA(Single Page Application, 單頁面應用)和前後端分離已經是主流. 基於Token的驗證非常適合這種構架. Difference between Token-based Auth and Cookie-based Auth 基於Cook

Asp.Net Core 3.1 學習4、Web Api 中基於JWTtoken驗證及Swagger使用

1、初始JWT 1.1、JWT原理        JWT(JSON Web Token)是目前最流行的跨域身份驗證解決方案,他的優勢就在於伺服器不用存token便於分散式開發,給APP提供資料用於前後端分離的專案。登入產生的 token的專案完全可以獨立與其他專案。當用

Spring Boot + Security + JWT 實現Token驗證+多Provider——登入系統

首先呢就是需求: 1、賬號、密碼進行第一次登入,獲得token,之後的每次請求都在請求頭裡加上這個token就不用帶賬號、密碼或是session了。 2、使用者有兩種型別,具體表現在資料庫中存使用者資訊時是分開兩張表進行儲存的。 為什麼會分開存兩張表呢,這個設計的時候是先設計的表結構,有分開的必要所以就

koa2,koa-jwttoken驗證實戰詳解

使用者身份驗證通常有兩種方式,一種是基於cookie的認證方式,另一種是基於token的認證方式。當前常見的無疑是基於token的認證方式。以下所提到的koa均為koa2版本。 token認證的優點是無狀態機制,在此基礎之上,可以實現天然的跨域和前後端分離等。 token認證的缺點是伺服器每次都需要對其進

基於Token的身份驗證——JWT

sig project 唯一標識 rocket 推薦 接收 含義 一個 esp 原文:基於Token的身份驗證——JWT初次了解JWT,很基礎,高手勿噴。 基於Token的身份驗證用來替代傳統的cookie+session身份驗證方法中的session。 JWT是啥?

基於gin框架和jwt-go中間件實現小程序用戶登陸和token驗證

expires 微信 處理 如果 .net local 切入點 小程序 err 本文核心內容是利用jwt-go中間件來開發golang webapi用戶登陸模塊的token下發和驗證,小程序登陸功能只是一個切入點,這套邏輯同樣適用於其他客戶端的登陸處理。 小程序登陸邏輯

Spring Security + JWT 實現基於Token的安全驗證

@Configuration @EnableWebSecurity //新增annotation 支援,包括(prePostEnabled,securedEnabled...) @EnableGlobalMethodSecurity(prePostEnabled = true) public class W

使用JWT 進行基於 Token 的身份驗證方法

quest 傳播 token system 過期 with 需要 驗證用戶名 ren 一般weby應用服務都使用有狀態的session來存儲用戶狀態以便認證有權限的用戶進行的操作。但服務器在做橫向擴展時,這種有狀態的session解決方案就受到了限制。所以在一些通常的大型w

基於 Token 的身份驗證

問題 for tar dci 返回 name 主題 算法 sha2 最近了解下基於 Token 的身份驗證,跟大夥分享下。很多大型網站也都在用,比如 Facebook,Twitter,Google+,Github 等等,比起傳統的身份驗證方法,Token 擴展性更強,也更安

webapi中使用token驗證JWT驗證

後端 erro filters missing 參考 做的 方法調用 reading minute 本文介紹如何在webapi中使用JWT驗證 準備 安裝JWT安裝包 System.IdentityModel.Tokens.Jwt 你的前端api登錄請求的方法,參考

redis jwt spring boot spring security 實現api token 驗證

BE output date art parent byte[] web rmi time 文章地址:http://www.haha174.top/article/details/258083 項目源碼:https://github.com/haha174/jwt-toke

基於token的鑒權機制 — JWT介紹

第三部分 認證用戶 http協議 png base64 服務 一個 邏輯 jwt   前言:在實際開發項目中,由於Http是一種無狀態的協議,我們想要記錄用戶的登錄狀態,或者為用戶創建身份認證的憑證,可以使用Session認證機制或者JWT認證機制。 什麽是JWT?   J

基於Token驗證

sig time timestamp mes coo 服務端 md5加密 時間 保存 什麽是token? token相當於是一個令牌,在用戶登錄的時候由服務器端生成(基於用戶名、時間戳、過期時間、發行者等信息進行簽名),然後發放給客戶端,客戶端將令牌保存,在以後需要登錄驗證

基於JWT的許可權驗證及實戰演練

前言: 大部分系統,除了大部分金融類的系統需要嚴格的安全框架(如shiro),一般的系統安全性要求都不是很高,只需要簡單的許可權驗證(比如登入驗證)即可,下面將簡單介紹JWT用法及登入驗證的實現方式(註解方式) jwt分析(原理啊什麼的廢話就不說了,只說用法) hea

SpringCloud利用閘道器攔截做Token驗證JWT方式) SpringCloud利用閘道器攔截做Token驗證JWT方式)

SpringCloud利用閘道器攔截做Token驗證(JWT方式) 2018年09月29日 15:51:50 19八9 閱讀數:23 更多

JavaWeb—基於Token的身份驗證 基於Token的WEB後臺認證機制

傳統身份驗證的方法 HTTP Basic Auth HTTP Basic Auth簡單點說明就是每次請求API時都提供使用者的username和password,簡言之,Basic Auth是配合RESTful API 使用的最簡單的認證方式,只需提供使用者名稱密碼即可,但由於有把使用者名稱密碼暴露給第三

基於 Token 的身份驗證:JSON Web Token

最近了解下基於 Token 的身份驗證,跟大夥分享下。很多大型網站也都在用,比如 Facebook,Twitter,Google+,Github 等等, 比起傳統的身份驗證方法,Token 擴充套件性更強

Nodejs專案中使用token驗證,jwt,jsonwebtoken

目前 在web框架中最流行的身份驗證是使用jsonwebtoken,簡稱jwt.可以設定加密方式,過期時間,存放個人資訊,逆解析. 抽空研究了一下nodejs的jwt如何做,下面來記錄一下 使用的包是 "jsonwebtoken": "^8.3.0" 包的github地址 主

基於 JWT + Refresh Token 的使用者認證實踐

HTTP 是一個無狀態的協議,一次請求結束後,下次在傳送伺服器就不知道這個請求是誰發來的了(同一個 IP 不代表同一個使用者),在 Web 應用中,使用者的認證和鑑權是非常重要的一環,實踐中有多種可用方案,並且各有千秋。 基於 Session 的會話管理 在 Web 應用發展的初期,大部

tp5.1 使用Composer安裝firebase php-jwt token驗證 API

PHP有很多jwt包,包括比如:lcobucci/jwt,我這裡使用firebase。可以從 git地址 下載 一、首先安裝Composer,已經安裝就跳過 不會的看這裡:https://blog.