title: Could we destroy/invalidate JWT token in Asp.NET Core?
body: <p>I use ASP.NET Core &amp; ASP.NET core Identity to generate a JWT token.</p>
  <p>On the client-side, my React (SPA) app calls API to create the token then include <code>Authorization: Bearer</code> <code>token from API</code> in subrequests.</p>
  <p>When I want to logout, how can I immediately invalidate the token on the server-side?</p>
  <p>Currently, I just delete the <code>bear</code> token on the client-side and not included in the next request?</p>
  <p><strong>Reference</strong>: <a href="https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/" rel="noreferrer">https://blogs.msdn.microsoft.com/webdev/2017/04/06/jwt-validation-and-authorization-in-asp-net-core/</a></p>
  <hr />
  <p>Code in <code>Configure</code> section in <code>Startup.cs</code></p>
  <pre><code>app.UseJwtBearerAuthentication(new JwtBearerOptions
  {
      AutomaticAuthenticate = true,
      AutomaticChallenge = true,
      TokenValidationParameters = new TokenValidationParameters
      {
          ValidIssuer = &quot;MySite&quot;,
          ValidAudience = &quot;MySite&quot;,
          ValidateIssuerSigningKey = true,
          IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(&quot;VERYL0NGKEYV@LUETH@TISSECURE&quot;)),
          ValidateLifetime = true
      }
  });
  </code></pre>
  <p>API to create a token</p>
  <pre><code>[HttpPost(&quot;Token&quot;)]
  public async Task&lt;IActionResult&gt; 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(&quot;VERYL0NGKEYV@LUETH@TISSECURE&quot;));
              var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
              var token = new JwtSecurityToken(
                  &quot;MySite&quot;,
                  &quot;MySite&quot;,
                  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);
      }
  }
  </code></pre>