代码之家  ›  专栏  ›  技术社区  ›  Hung Quach

我们可以在Asp中销毁/使JWT令牌无效吗。NET Core?

  •  18
  • Hung Quach  · 技术社区  · 7 年前

    我使用ASP。NET Core&ASP。NET核心标识来生成JWT令牌。

    在客户端,我的React(SPA)应用程序调用API来创建令牌,然后包括 Authorization: Bearer token from API 在子请求中。

    目前,我只是删除了 bear

    参考 https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/


    代码输入 Configure 中的部分 Startup.cs

    app.UseJwtBearerAuthentication(new JwtBearerOptions
    {
        AutomaticAuthenticate = true,
        AutomaticChallenge = true,
        TokenValidationParameters = new TokenValidationParameters
        {
            ValidIssuer = "MySite",
            ValidAudience = "MySite",
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VERYL0NGKEYV@LUETH@TISSECURE")),
            ValidateLifetime = true
        }
    });
    

    创建令牌的API

    [HttpPost("Token")]
    public async Task<IActionResult> CreateToken([FromBody] LoginModel model)
    {
        try
        {
            var user = await userManager.FindByNameAsync(model.Email);
            if (passwordHasher.VerifyHashedPassword(user, user.PasswordHash, model.Password) == PasswordVerificationResult.Success)
            {
    
                var claims = new[]
                {
                    new Claim(JwtRegisteredClaimNames.Sub, user.UserName),
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
                    new Claim(JwtRegisteredClaimNames.Email, user.Email)
                };
    
                var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("VERYL0NGKEYV@LUETH@TISSECURE"));
                var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                var token = new JwtSecurityToken(
                    "MySite",
                    "MySite",
                    claims,
                    expires: DateTime.UtcNow.AddMinutes(45),
                    signingCredentials: creds);
    
                return Ok(new
                {
                    Token = new JwtSecurityTokenHandler().WriteToken(token),
                    Expiration = token.ValidTo,
                });
            }
            return BadRequest();
        }
        catch (Exception ex)
        {
            logger.LogError(ex.ToString());
            return StatusCode((int)HttpStatusCode.InternalServerError);
        }
    }
    
    1 回复  |  直到 4 年前
        1
  •  27
  •   Tseng    7 年前

    您不能轻易地让它过期,而不失去它的一些优点或使解决方案变得更加复杂。

    最好的办法是使访问令牌时间足够短(<=5分钟),并使刷新令牌长时间运行。

    但如果你真的想立即使其失效,你需要做几件事:

    1. [如果服务器场/多个实例]您需要将其缓存在分布式缓存中,如redis
    2. [如果服务器场/多个实例]您需要通过消息总线(即使用Redis、RabbitMQ或Azure消息总线)将其传播到应用程序的每个实例,以便它们可以将其存储在本地内存缓存中(因此,每次您想要验证它时,您不必进行网络调用)
    3. 在授权期间,您需要验证ID是否仍在缓存中;否则,拒绝授权(401)
    4. 当用户注销时,您需要从缓存中删除项目。
    5. [如果场/多个实例]从分布式缓存中删除该项,并向所有实例发送消息,以便它们可以从本地缓存中删除该项