共计 2033 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要 Token 认证?
去年我们有个电商项目,在促销活动时突然出现登录失效问题。排查发现 Session 服务器内存爆满,导致新会话无法创建。另一次是新增服务器节点后,用户需要反复登录——这就是传统 Session 在分布式环境下的典型痛点:
- 服务器内存依赖性强
- 横向扩展困难
- 跨域支持复杂
JWT vs OAuth2.0 怎么选?
OAuth2.0 更适合第三方授权场景(如微信登录),而 JWT 的优势在于:
- 无状态:Token 自带验证信息
- 轻量级:Base64 编码体积小
- 自包含:减少数据库查询

实战:生成安全 Token
1. 基础配置
// appsettings.json
{
"Jwt": {
"Key": "你的 32 位安全密钥",
"Issuer": "yourdomain.com",
"ExpiryMinutes": 30
}
}
2. 核心服务封装
public class JwtService
{
private readonly IConfiguration _config;
public JwtService(IConfiguration config)
{_config = config;}
public string GenerateToken(User user)
{
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var claims = new[] {new Claim(JwtRegisteredClaimNames.Sub, user.Id),
new Claim("Role", user.Role), // 自定义 Claim
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(issuer: _config["Jwt:Issuer"],
expires: DateTime.Now.AddMinutes(Convert.ToDouble(_config["Jwt:ExpiryMinutes"])),
claims: claims,
signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256)
);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
验证中间件配置
// Startup.cs
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = false, // 根据需求调整
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = Configuration["Jwt:Issuer"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
性能优化关键点
算法选择
| 算法类型 | 验证速度 | 密钥管理 | 适用场景 |
|---|---|---|---|
| HS256 | 快 | 对称密钥 | 内部系统 |
| RS256 | 慢 30% | 公私钥对 | 开放 API |
黑名单策略
推荐 Redis 实现,内存占用公式:
总内存 = 失效 Token 数量 × (Token 长度 + 时间戳)
生产环境检查清单
-
强制 HTTPS:
services.AddHttpsRedirection(opts => opts.HttpsPort = 443); -
密钥轮换:建议每季度更换,新旧密钥并行 1 周
-
审计日志 示例:
INSERT INTO TokenAudit VALUES (GETDATE(), @UserId, @OldClaims, @NewClaims)
开放性问题
当面临 10 万 QPS 的 Token 验证压力时,你会:
- 使用内存缓存短期有效 Token?
- 采用 BloomFilter 过滤无效请求?
- 还是走 CDN 边缘验证?
欢迎在评论区分享你的架构方案!
正文完
