当前位置:首页 > C# > 正文

ASP.NET Core 刷新令牌存储详解(小白也能学会的安全令牌管理方案)

在现代 Web 应用开发中,ASP.NET Core 刷新令牌 是保障用户会话安全、提升用户体验的重要机制。本文将手把手教你如何在 ASP.NET Core 中实现 刷新令牌存储,即使你是编程新手,也能轻松掌握。

ASP.NET Core 刷新令牌存储详解(小白也能学会的安全令牌管理方案) 刷新令牌  刷新令牌存储 安全令牌管理 .NET 身份验证 第1张

什么是刷新令牌(Refresh Token)?

在基于 JWT(JSON Web Token)的身份验证系统中,访问令牌(Access Token)通常有效期较短(例如 15 分钟)。当它过期后,用户本应重新登录。但为了提升体验,我们可以使用刷新令牌来获取新的访问令牌,而无需用户再次输入账号密码。

刷新令牌的有效期较长(如 7 天或 30 天),但它必须被安全地存储和管理,这就是 .NET Core 身份验证 中的关键环节。

为什么需要安全的刷新令牌存储?

如果刷新令牌被泄露,攻击者可以长期冒充用户。因此,我们必须:

  • 将刷新令牌存储在数据库中,并与用户 ID 绑定
  • 设置过期时间
  • 支持令牌撤销(如用户登出时)
  • 使用 HTTPS 传输

步骤一:创建刷新令牌模型

首先,定义一个实体类来表示刷新令牌:

public class RefreshToken{    public int Id { get; set; }    public string Token { get; set; } = string.Empty;    public DateTime Expires { get; set; }    public bool IsRevoked { get; set; }    public string UserId { get; set; } = string.Empty;    // 导航属性(如果你使用 EF Core)    public ApplicationUser User { get; set; } = null!;}

步骤二:配置数据库上下文(EF Core)

在你的 ApplicationDbContext 中添加 DbSet:

public class ApplicationDbContext : IdentityDbContext{    public DbSet<RefreshToken> RefreshTokens { get; set; }    protected override void OnModelCreating(ModelBuilder builder)    {        base.OnModelCreating(builder);        builder.Entity<RefreshToken>()            .HasOne(rt => rt.User)            .WithMany()            .HasForeignKey(rt => rt.UserId);    }}

步骤三:生成并存储刷新令牌

在用户成功登录后,生成访问令牌和刷新令牌,并将刷新令牌存入数据库:

public async Task<LoginResponse> LoginAsync(string email, string password){    var user = await _userManager.FindByEmailAsync(email);    if (user == null || !await _userManager.CheckPasswordAsync(user, password))        throw new UnauthorizedAccessException("Invalid credentials.");    var accessToken = GenerateAccessToken(user);    var refreshToken = GenerateRefreshToken();    var tokenEntity = new RefreshToken    {        Token = refreshToken,        Expires = DateTime.UtcNow.AddDays(7),        UserId = user.Id    };    _context.RefreshTokens.Add(tokenentity);    await _context.SaveChangesAsync();    return new LoginResponse    {        AccessToken = accessToken,        RefreshToken = refreshToken    };}private string GenerateRefreshToken(){    var randomNumber = new byte[32];    using var rng = RandomNumberGenerator.Create();    rng.GetBytes(randomNumber);    return Convert.ToBase64String(randomNumber);}

步骤四:刷新访问令牌接口

当客户端携带刷新令牌请求新访问令牌时,验证并返回新令牌:

[HttpPost("refresh")]public async Task<IActionResult> RefreshToken([FromBody] RefreshRequest request){    var storedToken = await _context.RefreshTokens        .Include(rt => rt.User)        .FirstOrDefaultAsync(rt => rt.Token == request.Token);    if (storedToken == null ||        storedToken.IsRevoked ||        storedToken.Expires < DateTime.UtcNow)    {        return BadRequest("Invalid refresh token.");    }    // 可选:一次性使用(每次刷新后使旧令牌失效)    storedToken.IsRevoked = true;    // 生成新令牌对    var newRefreshToken = GenerateRefreshToken();    var newAccessToken = GenerateAccessToken(storedToken.User);    _context.RefreshTokens.Add(new RefreshToken    {        Token = newRefreshToken,        Expires = DateTime.UtcNow.AddDays(7),        UserId = storedToken.UserId    });    await _context.SaveChangesAsync();    return Ok(new { AccessToken = newAccessToken, RefreshToken = newRefreshToken });}

安全建议

  • 始终使用 HTTPS
  • 刷新令牌应存储在 HttpOnly Cookie 或安全的本地存储中(前端)
  • 实现令牌轮换(每次刷新后使旧令牌失效)
  • 定期清理过期的刷新令牌(可设后台任务)

总结

通过以上步骤,你已经掌握了在 ASP.NET Core 刷新令牌 系统中如何安全地实现 刷新令牌存储。这不仅提升了应用的 .NET Core 身份验证 安全性,也优化了用户体验。记住,良好的 安全令牌管理 是构建可信应用的基础。

希望这篇教程对你有帮助!如有疑问,欢迎留言交流。