JWT.NET的使用

来源:http://www.cnblogs.com/mrbug/archive/2017/12/11/8022826.html
-Advertisement-
Play Games

JWT是什麼 JWT全稱是Json Web Token,是一種用於雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規範。JWT作為一個開放的標準( RFC 7519 ),定義了一種簡潔的,自包含的方法用於通信雙方之間以Json對象的形式安全的傳遞信息。因為數字簽名的存在,這些信息是可信的,JWT ...


JWT是什麼

JWT全稱是Json Web Token,是一種用於雙方之間傳遞安全信息的簡潔的、URL安全的表述性聲明規範。JWT作為一個開放的標準( RFC 7519 ),定義了一種簡潔的,自包含的方法用於通信雙方之間以Json對象的形式安全的傳遞信息。因為數字簽名的存在,這些信息是可信的,JWT可以使用HMAC演算法或者是RSA的公私秘鑰對進行簽名。

 

JWT的結構

JWT一般由三段構成,用.號分隔開,第一段是header,第二段是payload,第三段是signature,例如:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiTXJCdWciLCJleHAiOjE1MTI5NTkzMDMuMCwianRpIjoibHVvemhpcGVuZyJ9.9iwGMHmS0mophyFgliLK15hs_eE770IchaZ-bWcX5c0

 

1、header

jwt的頭部承載兩部分信息:

  聲明類型。這裡是jwt
  聲明加密的演算法。通常直接使用 HMAC SHA256,其它還有RS256等

完整的頭部就像下麵這樣的JSON:

{
    "alg": "HS256",
    "typ": "JWT"
}

 然後將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9

 

2、playload

載荷就是存放有效信息的地方。這個名字像是特指飛機上承載的貨品,這些有效信息包含三個部分:

  標準中註冊的聲明
  公共的聲明
  私有的聲明

標準中註冊的聲明 (建議但不強制使用) :

    iss : jwt簽發者
    sub:jwt所面向的用戶
    aud:接收jwt的一方
    exp:jwt的過期時間,這個過期時間必須要大於簽發時間
    nbf:定義在什麼時間之前,該jwt都是不可用的.
    iat :jwt的簽發時間
    jti  :jwt的唯一身份標識,主要用來作為一次性token,從而迴避重放攻擊。

 

公共的聲明 :
公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息.但不建議添加敏感信息,因為該部分在客戶端可解密.

私有的聲明 :
私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。

定義一個playload

{
    "name": "MrBug",
    "exp": 1512959303,
    "jti": "luozhipeng"
}

 然後將其進行base64加密,得到Jwt的第二部分

eyJuYW1lIjoiTXJCdWciLCJleHAiOjE1MTI5NTkzMDMuMCwianRpIjoibHVvemhpcGVuZyJ9

 

3、signature

jwt的第三部分是一個簽證信息,這個簽證信息由三部分組成:

    header (base64後的)
    payload (base64後的)
    secret

這個部分需要base64加密後的header和base64加密後的payload使用.連接組成的字元串,然後通過header中聲明的加密方式進行加secret組合加密,然後就構成了jwt的第三部分。

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret'); // 9iwGMHmS0mophyFgliLK15hs_eE770IchaZ-bWcX5c0

將這三部分用.連接成一個完整的字元串,構成了最終的jwt:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiTXJCdWciLCJleHAiOjE1MTI5NTkzMDMuMCwianRpIjoibHVvemhpcGVuZyJ9.9iwGMHmS0mophyFgliLK15hs_eE770IchaZ-bWcX5c0

 
註意:secret是保存在伺服器端的,jwt的簽發生成也是在伺服器端的,secret就是用來進行jwt的簽發和jwt的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發jwt了。

 

如何應用

一般是在請求頭裡加入Authorization,並加上Bearer標註:

fetch('api/user/1', {
  headers: {
    'Authorization': 'Bearer ' + token
  }
})

 

服務端會驗證token,如果驗證通過就會返回相應的資源。整個流程就是這樣的:


 

安全相關

不應該在jwt的payload部分存放敏感信息,因為該部分是客戶端可解密的部分。

保護好secret私鑰,該私鑰非常重要。

如果可以,請使用https協議

如何在.net中使用

這裡要用到一個JWT.NET的第三方庫,可以通過NuGet的方式獲取,目前最新版是3.1.1,最新版只支持.net framework4.6及以上,如圖

因為,我項目中用的是.net framework4.5,所以我安裝的是JWT.NET 3.0.0,你可以使用VS 工具 /  NuGet包管理器 / 程式包管理器控制台 ,輸入以下命令手動安裝

Install-Package JWT -Version 3.0.0

 

 

1、創建token,此處,我們只需要自定義payload和secrect密鑰即可,可生成三段格式的字元串

IDateTimeProvider provider = new UtcDateTimeProvider();
var now = provider.GetNow();

var unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); // or use JwtValidator.UnixEpoch
var secondsSinceEpoch = Math.Round((now - unixEpoch).TotalSeconds);

var payload = new Dictionary<string, object>
{
        { "name", "MrBug" },                
        {"exp",secondsSinceEpoch+100 },
        {"jti","luozhipeng" }
};

Console.WriteLine(secondsSinceEpoch);

IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new JsonNetSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

var token = encoder.Encode(payload, secret);
Console.WriteLine(token);

 

 

 2、token解密

try
{
    IJsonSerializer serializer = new JsonNetSerializer();
    IDateTimeProvider provider = new UtcDateTimeProvider();
    IJwtValidator validator = new JwtValidator(serializer, provider);
    IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
    IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);

    var json = decoder.Decode(token, secret, verify: true);//token為之前生成的字元串
    Console.WriteLine(json);
}
catch (TokenExpiredException)
{
    Console.WriteLine("Token has expired");
}
catch (SignatureVerificationException)
{
    Console.WriteLine("Token has invalid signature");
}

 

 

3、自定義json解析器,只要繼承IJsonSerializer介面

public class CustomJsonSerializer : IJsonSerializer
{
    public string Serialize(object obj)
    {
        // Implement using favorite JSON Serializer
    }

    public T Deserialize<T>(string json)
    {
        // Implement using favorite JSON Serializer
    }
}

 

使用

IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
IJsonSerializer serializer = new CustomJsonSerializer();
IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

 

 

4、自定義JSON序列化

預設的JSON序列化由JsonNetSerializer完成,可以自定義序列化:

JsonSerializer customJsonSerializer = new JsonSerializer
{
    // All json keys start with lowercase characters instead of the exact casing of the model/property. e.g. fullName
    ContractResolver = new CamelCasePropertyNamesContractResolver(), 
    
    // Nice and easy to read, but you can also do Formatting.None to reduce the payload size (by hardly anything...)
    Formatting = Formatting.Indented,
    
    // The best date/time format/standard.
    DateFormatHandling = DateFormatHandling.IsoDateFormat,
    
    // Don't add key/values when the value is null.
    NullValueHandling = NullValueHandling.Ignore,
    
    // Use the enum string-value, not the implicit int value, e.g. "oolor" : "red"
    Converters.Add(new StringEnumConverter())
};
IJsonSerializer serializer = new JsonNetSerializer(customJsonSerializer);

 

 

 

整理自:

https://github.com/jwt-dotnet/jwt

http://www.jianshu.com/p/576dbf44b2ae

 


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

-Advertisement-
Play Games
更多相關文章
  • 有時候在窗體中執行不斷的GDI+操作的時候會出現閃速的狀況,除了修改窗體的參數,更應該解決刷新本身的問題,雙緩衝可能就是這樣來的。 方法1: 用GDI繪製在點陣圖上,然後再重新生成點陣圖 ...
  • 在上篇文章中,你跟著我寫了一個HelloWorld,本篇中,我們來談談一些C#程式中的小概念 1、C# 程式結構 一個 C# 程式主要包括以下部分: 命名空間聲明(Namespace declaration) 一個類(class) Class 方法 Class 屬性 一個 Main(主)方法 語句( ...
  • 來源:傳智播客 免費開發視頻。 問題:根據書名或出版社或作者查詢書籍信息。 知識點: 1.sql拼接 2.參數化查詢 3以下部分看起來簡單,但卻很難想到。 ...
  • 在win7,win10,vs2015,vs2017之間折騰了兩天,死活就是調不出來Mysql數據源。真是活見鬼了。 直接說方案吧。 一,卸載你所安裝過的mysql-connector-net、mysql-for-visualstudio-1.2.7、mysql-installer-community ...
  • 轉自https://www.cnblogs.com/bomo/archive/2013/02/26/2934055.html在處理較多的數據時,Bitmap中的Set/Get等函數在處理數據時比較慢,如果用記憶體法或者指針法會加快處理速度,這裡只學習了記憶體法,做一個記錄。首先我們在對Bitmap中的數... ...
  • 我們學習任務調度程式,通過非同步代碼與UI進行交互。所以本示例是創建Windows應用程式。 taskScheduler是負責如何執行任務,預設情況下是把task放入線程池中的工作線程中。 ...
  • 原文地址: unity打開資源管理器主要通過C#自帶的OpenFileName腳本。 實現打開資源管理器並選擇文件的腳本。 ...
  • 使用C#讀取Chrome瀏覽器的本地書簽文件,當前文件在C盤下用戶文件夾\AppData\Local\Google\Chrome\User Data\Default\下的Bookmarks 打開這個文件我們發現就是一個json文本文件 為了方便讀取操作還是將json字元串轉換為對象這裡分析json結 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...