Quantcast
Channel: Active questions tagged blazor - Stack Overflow
Viewing all articles
Browse latest Browse all 4839

How can I send my refresh tokens via httponly cookie to standalone blazor WebAssembly?

$
0
0

I've been trying for a couple days to implement refresh tokens into my ASP.NET Core Web API, but to no avail.

I've currently got an ASP.NET Core Web API that allows someone to log in with a username and password via my authentication endpoint. The API is accessed through a self written standalone blazor webassembly.

I was already using JWT tokens for authentication, storing it in localstorage; and this worked as a charm! But now I wanted to use refresh tokens so I can set the duration of my JWT tokens to be much lower.

This is the method in my authentication endpoint that creates the JWT and refresh tokens and sends them when the user is succesfully logged in:

[HttpPost("login")][SwaggerOperation(Summary = "Login", Description = "Login with username and password to get JWT token.")]public async Task<IActionResult> LoginAsync([FromBody] LoginRequestDto loginRequest){     // Check if user exists and password is correct     var user = _dbContext.Users.SingleOrDefault(u => u.Username == loginRequest.Username);     if (user is null || !BCrypt.Net.BCrypt.Verify(loginRequest.Password, user.Password))      {          return Unauthorized();      }     // Create auth token     var accessToken = _tokenProvider.Create(user);     // Create refresh token and add relevant data to database     var plainRefreshToken = RefreshTokenHelper.GenerateToken();     var refreshTokenHash = RefreshTokenHelper.HashToken(plainRefreshToken);     var refreshToken = new RefreshToken     {         TokenHash = refreshTokenHash,         Created = DateTime.UtcNow,         CreatedByIp = HttpContext.Connection.RemoteIpAddress?.ToString(),         Expires = DateTime.UtcNow.AddDays(_config.GetValue<int>("Jwt:RefreshExpirationInDays")),         UserId = user.Id,     };     _dbContext.refreshTokens.Add(refreshToken);     await _dbContext.SaveChangesAsync();     // Set HttpOnly cookie     Response.Cookies.Append("refreshToken", plainRefreshToken, new CookieOptions      {         HttpOnly = true,         Secure = true,         SameSite = SameSiteMode.None,         Expires = refreshToken.Expires     });     return Ok(new { Token = accessToken });}

As you can see above, the idea is that my refreshtoken is send in a HttpOnly cookie so it can't be intercepted. When debugging, I can tell that the plainrefreshtoken has been created... but I can't see it in my result when debugging my client project.

Even better yet, I've already made a handler that is supposed to store my JWT token in sessionstorage and try to refresh my jwt if it's expired

And I've also created a sessionstorage provider that is supposed to access the refresh method to refresh my JWT token.

This is my refresh method in the same authentication endpoint:

[HttpPost("refresh")]public async Task<IActionResult> Refresh(){    // Read token from cookie    var plainRefreshToken = Request.Cookies["refreshToken"];    if (string.IsNullOrEmpty(plainRefreshToken))     {        return Unauthorized();     }    var refreshTokenHash = RefreshTokenHelper.HashToken(plainRefreshToken);    var refreshToken = await _dbContext.refreshTokens.Include(x => x.User)        .SingleOrDefaultAsync(x => x.TokenHash == refreshTokenHash);    if (refreshToken is null || !refreshToken.IsActive)     {        return Unauthorized();     }    // revoke existing token and issue a new one    refreshToken.Revoked = DateTime.UtcNow;    refreshToken.RevokedByIp = HttpContext.Connection.RemoteIpAddress?.ToString();    var newPlainRefreshToken = RefreshTokenHelper.GenerateToken();    var newRefreshTokenHash = RefreshTokenHelper.HashToken(newPlainRefreshToken);    var newRefreshToken = new RefreshToken    {        TokenHash = newRefreshTokenHash,        Created = DateTime.UtcNow,        CreatedByIp = HttpContext.Connection.RemoteIpAddress?.ToString(),        Expires = DateTime.UtcNow.AddDays(_config.GetValue<int>("Jwt:RefreshExpirationInDays")),        UserId = refreshToken.UserId    };    refreshToken.ReplacedByTokenHash = newRefreshTokenHash;    _dbContext.refreshTokens.Add(newRefreshToken);    await _dbContext.SaveChangesAsync();    // Create the new access token    var newAccessToken = _tokenProvider.Create(refreshToken.User);    // Set new Token in cookie    Response.Cookies.Append("refreshToken", newPlainRefreshToken, new CookieOptions    {        HttpOnly = true,        Secure = true,        SameSite = SameSiteMode.None,        Expires = newRefreshToken.Expires    });    return Ok(new { Token = newAccessToken });}

But when debugging my refresh method, the Request.Cookies is 0, indicating that my refresh token doesn't get sent along.

I have no idea what I can do to get this to work... I am debugging both my API and client at the same time (they live in different solutions) and both on HTTPS with a self signed localhost certificate.


Viewing all articles
Browse latest Browse all 4839

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>