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

ASP.NET Core中优雅处理JWT过期问题(小白也能学会的JWT Token刷新与自动续期实战教程)

在现代Web开发中,ASP.NET Core JWT过期处理 是一个开发者经常遇到的问题。用户登录后获取的JWT(JSON Web Token)通常有固定的有效期,一旦过期,用户就需要重新登录,这会严重影响用户体验。本文将手把手教你如何在ASP.NET Core项目中实现JWT的自动刷新和优雅过期处理,即使你是编程小白,也能轻松掌握!

ASP.NET Core中优雅处理JWT过期问题(小白也能学会的JWT Token刷新与自动续期实战教程) Core JWT过期处理 JWT Token刷新机制 Core身份验证 JWT自动续期教程 第1张

为什么需要处理JWT过期?

JWT是一种无状态的身份验证机制,服务器签发Token后不再保存其状态。默认情况下,Token一旦过期就无法使用,用户必须重新登录。但在实际应用中,我们希望在用户活跃期间自动延长其会话,这就需要JWT Token刷新机制

核心思路:双Token机制

常见的解决方案是使用Access Token + Refresh Token 的组合:

  • Access Token:短期有效(如15分钟),用于API请求认证。
  • Refresh Token:长期有效(如7天),用于换取新的Access Token。

第一步:配置JWT服务

首先,在 Program.cs 中添加JWT认证服务:

// Program.csbuilder.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"]!))        };        // 添加Token过期事件处理        options.Events = new JwtBearerEvents        {            OnAuthenticationFailed = context =>            {                if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))                {                    context.Response.Headers.Add("Token-Expired", "true");                }                return Task.CompletedTask;            }        };    });builder.Services.AddAuthorization();

第二步:生成Access Token和Refresh Token

创建一个服务类来生成Token:

public class TokenService{    private readonly IConfiguration _config;    public TokenService(IConfiguration config)    {        _config = config;    }    public string GenerateAccessToken(string userId)    {        var tokenHandler = new JwtSecurityTokenHandler();        var key = Encoding.UTF8.GetBytes(_config["Jwt:Key"]!);        var tokenDescriptor = new SecurityTokenDescriptor        {            Subject = new ClaimsIdentity(new[] { new Claim("id", userId) }),            Expires = DateTime.UtcNow.AddMinutes(15), // 短期有效            Issuer = _config["Jwt:Issuer"],            Audience = _config["Jwt:Audience"],            SigningCredentials = new SigningCredentials(                new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)        };        var token = tokenHandler.CreateToken(tokenDescriptor);        return tokenHandler.WriteToken(token);    }    public string GenerateRefreshToken()    {        var randomNumber = new byte[32];        using var rng = RandomNumberGenerator.Create();        rng.GetBytes(randomNumber);        return Convert.ToBase64String(randomNumber);    }}

第三步:实现刷新Token的API

创建一个控制器,用于接收Refresh Token并返回新的Access Token:

[ApiController][Route("api/[controller]")]public class AuthController : ControllerBase{    private readonly TokenService _tokenService;    private readonly IRefreshTokenStore _refreshTokenStore; // 假设你有一个存储Refresh Token的服务    public AuthController(TokenService tokenService, IRefreshTokenStore refreshTokenStore)    {        _tokenService = tokenService;        _refreshTokenStore = refreshTokenStore;    }    [HttpPost("refresh")]    public async Task RefreshToken([FromBody] RefreshRequest request)    {        var userId = await _refreshTokenStore.ValidateRefreshToken(request.RefreshToken);        if (userId == null)            return BadRequest("Invalid refresh token");        var newAccessToken = _tokenService.GenerateAccessToken(userId);        var newRefreshToken = _tokenService.GenerateRefreshToken();        // 存储新的Refresh Token(可选:使旧的失效)        await _refreshTokenStore.StoreRefreshToken(userId, newRefreshToken);        return Ok(new { AccessToken = newAccessToken, RefreshToken = newRefreshToken });    }}public class RefreshRequest{    public string RefreshToken { get; set; } = string.Empty;}

第四步:前端如何配合?

当前端收到401错误且响应头包含 Token-Expired: true 时,应自动调用 /api/auth/refresh 接口获取新Token,然后重试原请求。这是实现JWT自动续期教程的关键一环。

安全注意事项

  • Refresh Token 必须安全存储(如HttpOnly Cookie)。
  • 每次使用Refresh Token后,建议使其失效并生成新的Refresh Token(旋转机制)。
  • 设置合理的Refresh Token有效期,并支持手动撤销。

总结

通过本文,你已经掌握了在ASP.NET Core身份验证中处理JWT过期的核心方法。使用双Token机制不仅能提升用户体验,还能保证系统的安全性。记住,良好的Token管理是构建健壮Web应用的基础。

如果你正在开发一个需要长时间保持用户登录状态的应用,这套ASP.NET Core JWT过期处理方案将是你不可或缺的利器!