共计 2128 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要 Token 认证?
曾经参与过一个电商平台项目,当用户量突破 50 万时,服务器开始频繁出现内存溢出。排查发现 Session 存储占用了 80% 的内存,每次大促时集群节点间的 Session 同步延迟导致用户频繁掉线。另一个政务云项目更棘手——由于浏览器禁用第三方 Cookie,跨域单点登录根本无法实现。

这些痛点催生了无状态认证方案,而 JWT(JSON Web Token) 凭借其自包含、紧凑的特性成为分布式系统的首选。与 OAuth2.0 相比,JWT 不需要每次请求都查询授权服务器,特别适合内部微服务之间的认证场景。
JWT 核心实现三步走
1. 密钥安全存储
避免硬编码密钥是安全底线,ASP.NET Core 的 IConfiguration 天然支持多环境配置:
// appsettings.Development.json
{
"Jwt": {
"SecretKey": "开发环境密钥至少 32 位",
"ExpiryMinutes": 30,
"Issuer": "yourdomain.com"
}
}
通过依赖注入获取配置:
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:SecretKey"]));
2. 令牌生成与签名
使用 Microsoft.IdentityModel.Tokens 创建包含自定义 Claims 的 Token:
var claims = new[] {new Claim(JwtRegisteredClaimNames.Sub, user.Id),
new Claim("role", user.IsAdmin ? "admin" : "user"), // 自定义声明
new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
};
var token = new JwtSecurityToken(issuer: Configuration["Jwt:Issuer"],
audience: "api",
claims: claims,
expires: DateTime.Now.AddMinutes(Convert.ToDouble(Configuration["Jwt:ExpiryMinutes"])),
signingCredentials: new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256)
);
3. 验证中间件配置
在 Startup.cs 中添加 JWT 验证管道:
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidIssuer = Configuration["Jwt:Issuer"],
ValidateAudience = true,
ValidAudience = "api",
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero, // 严格过期时间
IssuerSigningKey = securityKey
};
options.Events = new JwtBearerEvents
{
OnAuthenticationFailed = context =>
{if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
};
});
性能与安全平衡术
算法选型建议
- HS256:对称加密,速度快但密钥需严格保护
- RS256:非对称加密,验证端只需公钥,适合多系统场景
实测数据:在 4 核 8G 服务器上,HS256 每秒可处理 12,000 次验证,而 RS256 仅 3,500 次。
黑名单实现方案
对于主动注销的 Token,推荐使用 Redis 记录短期黑名单(TTL 设置为原 Token 剩余有效期)。100 万 TokenID 仅占用约 85MB 内存。
生产环境三大铁律
-
强制 HTTPS:在 Startup 的 Configure 方法开头添加:
app.UseHttpsRedirection(); -
密钥轮换 :每月通过配置中心更新密钥,保留旧密钥 1 天用于平滑过渡
-
审计日志 :记录包含用户 ID、角色变更等关键 Claim 的令牌签发事件
终极思考题
当系统需要处理 10 万 QPS 的 Token 验证时,可以考虑:
– 在内存缓存中存储最近验证通过的 Token 签名(LRU 策略)
– 使用 BloomFilter 快速过滤无效 Token
– 对 JWT 进行分段验证,先检查基本格式再验证签名
Token 认证不是银弹,但正确实施能让你的 API 既安全又高效。在实际项目中,你会如何设计高并发场景下的 Token 缓存策略呢?
