認證方案之初步認識JWT

来源:https://www.cnblogs.com/i3yuan/archive/2019/09/14/11519431.html
-Advertisement-
Play Games

前言: 現在越來越多的項目或多或少會用到JWT,為什麼會出現使用JWT這樣的場景的呢? 假設現在有一個APP,後臺是分散式系統。APP的首頁模塊部署在上海機房的伺服器上,子頁面模塊部署在深圳機房的伺服器上。此時你從首頁登錄了該APP,然後跳轉到子頁面模塊。session在兩個機房之間不能同步,用戶是 ...


前言

  現在越來越多的項目或多或少會用到JWT,為什麼會出現使用JWT這樣的場景的呢?

  假設現在有一個APP,後臺是分散式系統。APP的首頁模塊部署在上海機房的伺服器上,子頁面模塊部署在深圳機房的伺服器上。此時你從首頁登錄了該APP,然後跳轉到子頁面模塊。session在兩個機房之間不能同步,用戶是否需要重新登錄?

傳統的方式(cookie+session)需要重新登錄,用戶體驗不好。session共用(在多台物理機之間傳輸和複製session)方式對網路IO的壓力大,延遲太長,用戶體驗也不好。

  說到這大家可能會想到,用伺服器的session_id存儲到cookies中也能做到,為什麼非要用token呢?網上有許多文章來比較token和session的優缺點,其實,開發web應用的話用哪種都行。但如果是開發api介面,前後端分離,最好使用token,為什麼這麼說呢,因為session+cookies是基於web的。但是針對 api介面,可能會考慮到移動端,app是沒有cookies和session的。

  Session方式存儲用戶信息的最大問題在於要占用大量伺服器記憶體,增加伺服器的開銷。

  而JWT方式將用戶狀態分散到了客戶端中,可以明顯減輕服務端的記憶體壓力。Session的狀態是存儲在伺服器端,客戶端只有session id;而Token的狀態是存儲在客戶端

原理

JSON Web Token(縮寫 JWT)

    JWT 的原理是,伺服器認證以後,生成一個 JSON 對象,發回給用戶,以後,用戶與服務端通信的時候,都要發回這個 JSON 對象。

  伺服器完全只靠這個對象認定用戶身份。為了防止用戶篡改數據,伺服器在生成這個對象的時候,會加上簽名。

  伺服器就不保存任何 session 數據了,也就是說,伺服器變成無狀態了,從而比較容易實現擴展。

組合

 JWT 的三個部分依次是:Header(頭部)、Payload(負載)、Signature(簽名)

寫成一行,就是下麵的樣子。

Header.Payload.Signature

 一、Header

header典型的由兩部分組成:token的類型(“JWT”)和演算法名稱(比如:HMAC SHA256或者RSA等等)

        {
          "alg": "HS256", //alg屬性表示簽名的演算法(algorithm),預設是 HMAC SHA256(寫成 HS256)
          "typ": "JWT"   //typ屬性表示這個令牌(token)的類型(type)
        }

然後用Base64對這個JSON編碼就得到JWT的第一部分

二、Payload

JWT的第二部分是payload,它包含聲明(要求)。聲明是關於實體(通常是用戶)和其他數據的聲明

JWT 規定了7個官方欄位

  • iss (issuer):簽發人
  • exp (expiration time):過期時間
  • sub (subject):主題
  • aud (audience):受眾
  • nbf (Not Before):生效時間
  • iat (Issued At):簽發時間
  • jti (JWT ID):編號

除了官方欄位,你還可以在這個部分定義私有欄位,下麵就是一個例子

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
註意,不要在JWT的payload或header中放置敏感信息,除非它們是加密的

三、Signature

Signature 部分是對前兩部分的簽名,防止數據篡改。簽名是用於驗證消息在傳遞過程中有沒有被更改,並且,對於使用私鑰簽名的token,它還可以驗證JWT的發送方是否為它所稱的發送方。

為了得到簽名部分,你必須有編碼過的header、編碼過的payload、一個秘鑰,簽名演算法是header中指定的那個,然對它們簽名即可。按照下麵的公式產生簽名。

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

算出簽名以後,把 Header、Payload、Signature 三個部分拼成一個字元串,每個部分之間用"點"(.)分隔,就可以返回給用戶。

 

開始

 一、客戶端收到伺服器返回的 JWT,可以儲存在 Cookie 裡面,也可以儲存在 localStorage。

此後,客戶端每次與伺服器通信,都要帶上這個 JWT。你可以把它放在 Cookie 裡面自動發送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization欄位裡面。

Authorization: Bearer <token>

二、JWT 就放在 POST 請求的數據體裡面,那麼跨源資源共用(CORS)將不會成為問題,因為它不使用cookie

1.應用(或者客戶端)想授權伺服器請求授權。例如,如果用授權碼流程的話,就是/oauth/authorize

2.當授權被許可以後,授權伺服器返回一個access token給應用

3.應用使用access token訪問受保護的資源(比如:API)

特點

1.JWT 預設是不加密,但也是可以加密的。生成原始 Token 以後,可以用密鑰再加密一次。

2.JWT 不加密的情況下,不能將秘密數據寫入 JWT。

3.JWT 的最大缺點是,由於伺服器不保存 session 狀態,因此無法在使用過程中廢止某個 token,或者更改 token 的許可權。也就是說,一旦 JWT 簽發了,在到期之前就會始終有效,除非伺服器部署額外的邏輯。

4.JWT 本身包含了認證信息,一旦泄露,任何人都可以獲得該令牌的所有許可權。為了減少盜用,JWT 的有效期應該設置得比較短。對於一些比較重要的許可權,使用時應該再次對用戶進行認證。

註意

JWT 是 JSON 格式的被加密了的字元串

JWT 的核心是密鑰,就是 JSON 數據。這是你關心的,並希望安全傳遞出去的數據。JWT 如何做到這一點,並使你信任它,就是加密簽名。

 

被篡改之後

 

 

總結

參考官方文檔:JSON Web Tokens

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Eureka服務治理 下麵請聽第一個話題,母。。。咳咳,拿錯書了。 Eureka簡介 eureka是什麼呢? 簡單來說呢,當我的微服務應用多了起來,一個一個寫死再程式里是件很不優雅的事情,而且同一服務可能會多個實例存在,來對服務分流,就是負載均衡。 所以,我們需要一個位置來存放服務的訪問列表,以供消 ...
  • [TOC] 控制流程之for迴圈 基本語法 while可以迴圈一切事物 for 迴圈提供了一種手段,不依賴索引取值 for+break for+continue for+else for迴圈不被break終止就執行else後面的代碼,否則就不執行 for迴圈列印lodaing 數字類型內置方法 整型 ...
  • [TOC] 原文鏈接: "QRowTable表格控制項(五) 重寫表頭排序、支持第三次單擊恢復預設排序" 一、原生表格 開發客戶端程式的方式月來源多了,現在很流行的libcef、electron等等都可以作為快速開發客戶端軟體的方案,但是如果需要一個號的用戶體驗,還是離不開原生化的開發,雖然慢,但是性 ...
  • 簡介 簡單來說,springcloud的就是由一組springboot應用(服務)組成,相互之間通過REST等方式進行通信。 兩個springboot應用,其中一個作為服務提供者,一個作為服務消費者,我認為這就構成了一個最簡單的springcloud應用,之後其他的工具都是為這兩個應用來服務的。 我 ...
  • 源代碼:# dict1 是 字典 , 用來對應相應元素的下標,我們將文件轉成列表,對應的也就是文件的下標,通過下標來找文件元素dict1 = {'sort':0 , 'name':1 ,'age':2 ,'phone':3 ,'job':4 }#將最後需要列印的信息轉成列表的形式def p_mess ...
  • 今日所學: /* 2019.08.19開始學習,此為補檔。 */ 1.this: ①this是成員方法的一個特殊的固有的本地變數,它表達了調用這個方法的那個對象。 ②在成員方法內部直接調用自己(this)的其他方法。 2.本地(局部)變數: ①定義在方法內部的變數是本地變數。 ②本地變數的生存期和作 ...
  • 一、前言 一直想寫一篇Dpper的定製化擴展的文章,但是裡面會設計到對Lambda表達式的解析,而解析Lambda表達式,就必須要知道表達式樹的相關知識點。我希望能通過對各個模塊的知識點或者運用能夠多一點的講解,能夠幫助到園友瞭解得更多。雖然講解得不全面,如果能成為打開這塊的一把鑰匙,也是蝸牛比較欣 ...
  • 一、前言 剛開始工作的時候,覺得委托和事件有些神秘,而當你理解他們之後,也覺得好像沒有想象中的那麼難。在項目中運用委托和事件,你會發現他非常棒,這篇博文算是自己對委托和事件的一次梳理和總結。 二、委托 C#中的委托,相當於C++中的指針函數,但委托是面向對象的,是安全的,是一個特殊的類,當然他也是引 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...