C#后端Web API实战:从零构建安全的Token认证体系

1次阅读
没有评论

共计 2033 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

为什么需要 Token 认证?

去年我们有个电商项目,在促销活动时突然出现登录失效问题。排查发现 Session 服务器内存爆满,导致新会话无法创建。另一次是新增服务器节点后,用户需要反复登录——这就是传统 Session 在分布式环境下的典型痛点:

  • 服务器内存依赖性强
  • 横向扩展困难
  • 跨域支持复杂

JWT vs OAuth2.0 怎么选?

OAuth2.0 更适合第三方授权场景(如微信登录),而 JWT 的优势在于:

  • 无状态:Token 自带验证信息
  • 轻量级:Base64 编码体积小
  • 自包含:减少数据库查询

C# 后端 Web API 实战:从零构建安全的 Token 认证体系

实战:生成安全 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 长度 + 时间戳)

生产环境检查清单

  1. 强制 HTTPS

    services.AddHttpsRedirection(opts => opts.HttpsPort = 443);

  2. 密钥轮换:建议每季度更换,新旧密钥并行 1 周

  3. 审计日志 示例:

    INSERT INTO TokenAudit 
    VALUES (GETDATE(), @UserId, @OldClaims, @NewClaims)

开放性问题

当面临 10 万 QPS 的 Token 验证压力时,你会:

  • 使用内存缓存短期有效 Token?
  • 采用 BloomFilter 过滤无效请求?
  • 还是走 CDN 边缘验证?

欢迎在评论区分享你的架构方案!

正文完
 0
评论(没有评论)