共计 3099 个字符,预计需要花费 8 分钟才能阅读完成。
背景与痛点
在 WebAPI 开发中,身份验证是保护接口安全的第一道防线。传统的 Session 验证方式虽然简单,但在分布式系统和前后端分离架构中逐渐暴露出问题:

- 服务器需要存储 Session 状态,增加内存压力
- 不利于水平扩展,跨服务器共享 Session 复杂
- 移动端和跨域场景支持不佳
相比之下,Token 验证 (特别是 JWT) 具有明显优势:
- 无状态:服务器不需要存储 Token
- 跨域友好:天然支持 CORS
- 移动端适配:更适合 APP 开发
- 自包含:Token 本身包含用户信息
JWT 技术选型
JWT(JSON Web Token)是目前最流行的 Token 实现方案,由三部分组成:
- Header:包含算法类型和 token 类型
- Payload:存放用户信息和 claims(声明)
- Signature:对前两部分的签名,防止篡改
JWT 的工作流程很简单:
- 用户登录成功后,服务器生成 JWT 返回给客户端
- 客户端后续请求都在 Header 中携带此 Token
- 服务器验证 Token 有效性并处理请求
核心实现步骤
1. 安装必要的 NuGet 包
在项目中添加以下包:
Microsoft.AspNetCore.Authentication.JwtBearer
System.IdentityModel.Tokens.Jwt
Microsoft.IdentityModel.Tokens
2. 实现 JWT 生成服务
创建 Token 生成服务类:
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 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(30),
signingCredentials: credentials);
return new JwtSecurityTokenHandler().WriteToken(token);
}
}
3. 配置认证中间件
在 Program.cs 中添加认证服务:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = builder.Configuration["Jwt:Issuer"],
ValidAudience = builder.Configuration["Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
};
});
4. 添加授权策略
可以基于角色配置不同的授权策略:
builder.Services.AddAuthorization(options =>
{
options.AddPolicy("AdminOnly", policy =>
policy.RequireRole("Admin"));
options.AddPolicy("UserOnly", policy =>
policy.RequireRole("User"));
});
完整代码示例
登录 Controller
[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{
private readonly JwtService _jwtService;
public AuthController(JwtService jwtService)
{_jwtService = jwtService;}
[HttpPost("login")]
public IActionResult Login([FromBody] LoginRequest request)
{
// 这里应该是用户验证逻辑
if (request.Username != "admin" || request.Password != "123456")
return Unauthorized();
var user = new User
{
Username = request.Username,
Email = "admin@example.com",
Role = "Admin"
};
var token = _jwtService.GenerateToken(user);
return Ok(new { Token = token});
}
}
受保护的 API Controller
[ApiController]
[Route("api/[controller]")]
[Authorize] // 要求认证
public class ProtectedController : ControllerBase
{[HttpGet]
[Authorize(Policy = "AdminOnly")] // 要求 Admin 角色
public IActionResult Get()
{return Ok("This is protected data for admins only!");
}
}
安全考量
- Token 过期:设置合理的过期时间(如 30 分钟)
- 刷新 Token:实现刷新机制避免频繁登录
- HTTPS:必须使用 HTTPS 传输 Token
- 敏感信息:不要在 Payload 中存储敏感数据
- 密钥保护:使用强密钥并妥善保管
避坑指南
- 时钟偏差问题:确保服务器时间准确,或适当放宽时间验证
- 签名验证失败:检查密钥是否一致,是否有特殊字符
- 跨域问题:正确配置 CORS 策略
- 性能问题:避免在 Token 中存储过多数据
进阶思考
- 基于声明 (Claim) 的更细粒度权限控制
- 多因素认证集成
- 审计日志记录
- 限流防刷机制
总结
JWT 为 WebAPI 提供了一种简单、安全、可扩展的身份验证方案。通过本文的实现,你已经掌握了核心的 JWT 集成方法。下一步可以探索:
- OAuth2.0 集成
- OpenID Connect
- 自定义 Token 加密方式
- 分布式系统的 Token 共享方案
希望这篇实战指南能帮助你快速构建安全的 API 系统。在实际项目中,记得根据具体需求调整安全策略和实现细节。
正文完
