You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JWT时如何创建Logout端点?附登录实现代码

JWT身份认证下实现Logout端点的方案

因为JWT是无状态的,服务器不会存储已生成的token,所以Logout不能简单靠服务器销毁token,需要结合客户端操作和可选的服务器端校验机制来实现:

1. 基础Logout端点实现(客户端主导)

先创建一个Logout接口,核心是清理服务器端的用户登录关联信息,同时通知客户端丢弃本地token:

public async Task<IActionResult> Logout()
{
    // 清除服务器端存储的用户登录相关信息(对应你之前SetLoginInfo存储的内容)
    await _authManager.ClearLoginInfo(Request);
    
    // 返回成功响应,触发客户端清理token
    return Ok(new { Message = "退出登录成功" });
}

客户端必须执行的操作

  • 收到Logout成功响应后,立即删除本地存储的JWT token(比如localStorage、sessionStorage或Cookie)
  • 后续请求不再携带该token

2. 增强安全:维护Token黑名单(可选)

如果要防止已退出的token在过期前被恶意复用,可在服务器端维护一个token黑名单:

步骤1:实现黑名单存储逻辑

用内存缓存(开发环境)、Redis或数据库存储无效token,缓存过期时间与token自身过期时间保持一致:

在AuthManager中添加黑名单相关方法:

private readonly IMemoryCache _cache;

// 构造函数注入IMemoryCache
public AuthManager(IMemoryCache cache)
{
    _cache = cache;
}

public async Task AddTokenToBlacklist(string token)
{
    var tokenHandler = new JwtSecurityTokenHandler();
    var jwtToken = tokenHandler.ReadJwtToken(token);
    var expiresAt = jwtToken.ValidTo;
    
    // 将token存入缓存,过期时间同步token有效期
    await Task.Run(() => 
        _cache.Set($"Blacklist:{token}", true, expiresAt - DateTime.UtcNow));
}

public bool IsTokenBlacklisted(string token)
{
    return _cache.TryGetValue($"Blacklist:{token}", out _);
}

步骤2:修改Logout端点,将当前token加入黑名单

从请求头获取客户端携带的JWT token,加入黑名单:

public async Task<IActionResult> Logout()
{
    // 从Authorization头提取token
    var authHeader = Request.Headers["Authorization"].FirstOrDefault();
    if (!string.IsNullOrEmpty(authHeader) && authHeader.StartsWith("Bearer "))
    {
        var token = authHeader.Substring("Bearer ".Length).Trim();
        await _authManager.AddTokenToBlacklist(token);
    }
    
    // 清除服务器端登录信息
    await _authManager.ClearLoginInfo(Request);
    
    return Ok(new { Message = "退出登录成功" });
}

步骤3:在认证流程中校验黑名单

在JWT认证中间件中添加黑名单校验,拦截作废的token:

// 在Startup/Program.cs的认证配置中添加
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 保留你已有的校验参数
        };
        
        options.Events = new JwtBearerEvents
        {
            OnTokenValidated = context =>
            {
                var authManager = context.HttpContext.RequestServices.GetRequiredService<IAuthManager>();
                var token = context.SecurityToken as JwtSecurityToken;
                
                if (authManager.IsTokenBlacklisted(token.RawData))
                {
                    context.Fail("Token已被作废");
                }
                
                return Task.CompletedTask;
            }
        };
    });

3. 额外注意事项

  • 客户端清理token是核心,即使没有黑名单机制,只要客户端不再携带token,就无法通过认证
  • 黑名单机制适合高安全要求场景,注意控制存储容量,避免内存或存储资源浪费
  • 如果用HttpOnly Cookie存储token,可在Logout端点直接设置Cookie过期:Response.Cookies.Delete("JwtToken");

内容的提问来源于stack exchange,提问作者QasemBSK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 19:45:31