共计 2474 个字符,预计需要花费 7 分钟才能阅读完成。
背景与痛点
在构建现代 WebAPI 时,安全验证是必不可少的环节。传统的 Session 或 Cookie 验证方式存在诸多不足,比如服务器需要维护会话状态、跨域访问受限、移动端兼容性差等问题。而 JWT (JSON Web Token) 作为一种轻量级的认证方案,完美解决了这些痛点。

JWT 核心概念
JWT 由三部分组成,用点号连接:
- Header:包含 token 类型和签名算法
- Payload:存放用户信息和附加数据
- Signature:对前两部分签名,防止篡改
JWT 的优势在于:
- 无状态:服务器不需要存储会话信息
- 跨域:天然支持跨域访问
- 灵活性:可以携带任意自定义信息
实现步骤
1. 安装必要 NuGet 包
首先需要安装以下 NuGet 包:
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package System.IdentityModel.Tokens.Jwt
2. 配置 JWT 参数
在 appsettings.json 中添加配置:
{
"Jwt": {
"Key": "your_super_secret_key_at_least_32_chars",
"Issuer": "your_issuer",
"Audience": "your_audience",
"ExpireMinutes": 60
}
}
3. 实现 Token 生成服务
创建一个 Token 服务类:
public class TokenService
{
private readonly IConfiguration _config;
public TokenService(IConfiguration config)
{_config = config;}
public string GenerateToken(User user)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
var claims = new[]
{new Claim(ClaimTypes.NameIdentifier, user.Username),
new Claim(ClaimTypes.Email, user.Email),
new Claim(ClaimTypes.Role, user.Role)
};
var token = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Audience"],
claims,
expires: DateTime.Now.AddMinutes(Convert.ToDouble(_config["Jwt:ExpireMinutes"])),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
4. 添加验证中间件
在 Startup.cs 中配置:
public void ConfigureServices(IServiceCollection services)
{services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidAudience = Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
});
services.AddScoped<TokenService>();}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{app.UseAuthentication();
app.UseAuthorization();
// 其他中间件...
}
安全考量
- Token 存储安全
- 客户端应存储在
HttpOnlyCookie 或localStorage -
避免在 URL 中传输 Token
-
防止重放攻击
- 设置较短的过期时间
-
可以使用 JTI (JWT ID) 实现一次性 Token
-
密钥管理
- 生产环境不要硬编码密钥
- 使用 Key Vault 或环境变量存储密钥
- 定期轮换密钥
性能优化
- 验证过程优化
- 对于频繁验证的场景,可以缓存验证结果
-
减少 Token 中不必要的数据
-
大规模部署
- 考虑使用分布式缓存存储吊销的 Token
- 负载均衡环境下确保时钟同步
避坑指南
- 签名验证失败
- 确保密钥长度足够(至少 256 位)
-
检查密钥是否被意外修改
-
Token 过期无效
- 服务器时间与客户端时间不同步
-
检查时区设置
-
跨域问题
- 确保 CORS 配置正确
-
添加
Access-Control-Allow-Credentials头 -
信息泄露
- 不要在 Token 中存储敏感信息
-
使用 HTTPS 传输
-
性能瓶颈
- 避免在 Token 中存储过多数据
- 使用高效的签名算法(如 HS256)
进一步学习
在实际项目中,建议根据具体需求调整 Token 的有效期和包含的信息。对于更高安全要求的场景,可以考虑结合 Refresh Token 机制或双因素认证。
正文完
