C# (.NET) 中的 JWT 令牌:创建、验证和校验
JSON Web Token (JWT) 是一种基于 JSON 格式的开放标准 (RFC 7519),用于创建访问令牌。JWT 广泛应用于现代 Web 应用程序中,用于客户端和服务器之间的身份验证和信息交换。在本文中,我们将详细介绍如何在 C# (.NET) 生态系统中使用 JWT 令牌,包括令牌的创建、签名、验证和校验。
JWT 的主要组成部分
JWT 由三部分组成,各部分之间用点号分隔:
- Header — 标头,包含令牌类型和签名算法的信息
- Payload — 有效载荷,包含数据(声明)
- Signature — 签名,确保令牌的完整性
JWT 令牌示例:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
安装必要的包
要在 .NET 中使用 JWT,需要安装 System.IdentityModel.Tokens.Jwt 包。可以通过 NuGet 包管理器或 .NET CLI 进行安装:
dotnet add package System.IdentityModel.Tokens.Jwt为了与 ASP.NET Core 集成,可能还需要安装 Microsoft.AspNetCore.Authentication.JwtBearer:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer在 C# 中创建 JWT 令牌
我们来看一个使用对称密钥 (HMAC SHA256) 创建 JWT 令牌的完整示例:
using System;using System.IdentityModel.Tokens.Jwt;using System.Security.Claims;using System.Text;using Microsoft.IdentityModel.Tokens;
public class JwtService{ private readonly string _secretKey; private readonly string _issuer; private readonly string _audience;
public JwtService(string secretKey, string issuer, string audience) { _secretKey = secretKey; _issuer = issuer; _audience = audience; }
public string GenerateToken(string userId, string userName, string role) { var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_secretKey)); var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var claims = new[] { new Claim(ClaimTypes.NameIdentifier, userId), new Claim(ClaimTypes.Name, userName), new Claim(ClaimTypes.Role, role), new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), new Claim(JwtRegisteredClaimNames.Iat, new DateTimeOffset(DateTime.UtcNow).ToUnixTimeSeconds().ToString()) };
var token = new JwtSecurityToken( issuer: _issuer, audience: _audience, claims: claims, expires: DateTime.UtcNow.AddHours(1), signingCredentials: credentials );
return new JwtSecurityTokenHandler().WriteToken(token); }}验证和校验 JWT 令牌
要验证令牌的真实性并提取数据,可以使用 ValidateToken 方法:
public ClaimsPrincipal ValidateToken(string token){ var tokenHandler = new JwtSecurityTokenHandler(); var key = Encoding.UTF8.GetBytes(_secretKey);
try { var principal = tokenHandler.ValidateToken(token, new TokenValidationParameters { ValidateIssuerSigningKey = true, IssuerSigningKey = new SymmetricSecurityKey(key), ValidateIssuer = true, ValidIssuer = _issuer, ValidateAudience = true, ValidAudience = _audience, ValidateLifetime = true, ClockSkew = TimeSpan.Zero\