共计 2539 个字符,预计需要花费 7 分钟才能阅读完成。
背景与痛点
在 Web API 开发中,认证是确保资源安全访问的第一道防线。传统的 Cookie/Session 模式虽然简单,但在分布式系统中存在明显局限性:

- 扩展性问题 :Session 需要服务器存储状态,水平扩展时需额外处理 Session 共享
- CSRF 风险 :依赖浏览器自动携带 Cookie 的特性容易被伪造请求攻击
- 移动端适配 :原生 App 处理 Cookie 不如 Web 端自然
为什么选择 JWT?
对比常见认证方案:
- OAuth2:适合第三方授权,但实现复杂
- Basic Auth:每次请求携带明文凭证,安全性低
- JWT:自包含令牌、无状态、支持跨域,API 场景首选
核心实现
1. 安装必要包
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
2. 生成 Token 的 Service
public class TokenService
{
private readonly IConfiguration _config;
public TokenService(IConfiguration config)
{_config = config;}
public string GenerateToken(User user)
{
// 1. 准备 Claims(令牌携带的信息)var claims = new List<Claim>
{new(JwtRegisteredClaimNames.Sub, user.Id),
new(JwtRegisteredClaimNames.Email, user.Email),
new("custom_claim", "示例自定义声明")
};
// 2. 从配置读取密钥(生产环境应使用非对称加密)var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
// 3. 生成签名凭证
var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
// 4. 创建 Token 描述
var tokenDescriptor = new SecurityTokenDescriptor
{Subject = new ClaimsIdentity(claims),
Expires = DateTime.UtcNow.AddMinutes(30), // 过期时间
SigningCredentials = creds,
Issuer = _config["Jwt:Issuer"]
};
// 5. 生成 Token
var tokenHandler = new JwtSecurityTokenHandler();
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
}
3. Startup 配置
// Program.cs
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = false, // 根据需求调整
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
// 中间件配置(注意顺序!)app.UseAuthentication();
app.UseAuthorization();
安全加固
1. 令牌生命周期管理
- 设置合理过期时间(如 30 分钟)
- 实现 Refresh Token 机制:
// 在登录接口返回 return Ok(new { access_token = token, refresh_token = GenerateRefreshToken(), expires_in = 1800 });
2. 防范重放攻击
- 使用 JWT 的
jti(JWT ID)声明 - 服务端维护短期黑名单
3. 密钥管理
- 开发环境:
// appsettings.Development.json "Jwt": { "Key": "至少 16 字符的复杂字符串", "Issuer": "your-api.com" } - 生产环境:
- 使用 Azure Key Vault 等专用服务
- 定期轮换密钥
避坑指南
常见错误
- 硬编码密钥 :
- ❌
var key = "my_secret_key"; -
✅ 从安全配置源读取
-
过度 Claims:
- JWT 默认不加密,敏感信息应避免放入
- 大体积 Token 会增加每个请求的开销
性能优化
- 减少不必要的 Claims
- 对高频接口使用缓存验证结果
动手练习
尝试实现基于角色的访问控制:
1. 在生成 Token 时添加 Role Claim
2. 创建 Policy 验证角色:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireClaim("role", "admin"));
});
3. 在 Controller 上使用:
[Authorize(Policy = "AdminOnly")]
public class AdminController : ControllerBase
完整示例代码已托管至 GitHub:[示例仓库链接](请替换为实际链接)
总结
通过本文的实践,我们完成了:
1. 理解 JWT 在 API 认证中的优势
2. 实现端到端的 Token 生成与验证
3. 掌握生产级安全配置要点
4. 了解常见陷阱与优化方向
建议在实际项目中结合具体需求调整 Token 策略,例如添加指纹增强安全性或实现分布式 Token 吊销机制。
正文完
