.NET Core web application Access and Refresh Token Cookie set it in HttpRequest

52 Views Asked by At

I have an ASP.NET Core web and Web API application. The API will provide access and refresh token after user login, then UI application saves the data with response.cookie.append("refresh token", refresh token) with expiry time of 30 minutes for refresh and 10 minutes for the access token.

The issue is when user becomes idle for 10 or more minutes, the access token becomes null and when he tries to make a request or redirect to another page or some action in ui that it will hit my base controller and before making the HttpClient call to my Web API, I am checking my token validity so we don't have access token at that time; I am calling my API with refresh token and getting the new access and refresh token and save it in HttpContext.Response.Cookie.Append way.

But still we are having the existing request which still pending when i try to get the new access and refresh token from the saved cookie to make the client call to fetch record from api my access token is still null also with old refresh token values because the current request does not get updated with newly appended token.

i am using onauthorize custom attribute in my controller top to allow only users with access and refresh token there only i am setting access and refresh token in cookie if refresh token is null or expired

I can't use session or neither js I need to figure it out by using C#

Thanks in advance

1

There are 1 best solutions below

1
Jalpa Panchal On

To resolve your issue you have to refresh the token before it expire or right after on its expiration without interfering the current user request, you could follow this below suggestion:

You could use the middleware which will help you to check the token validity on every request when it is about to expire or expired refresh the token and proceed with that new refreshed token. You could store the new token in the HttpContext.Items so that you can access anywhere during its lifetime. in your API call first check HttpContext.Items for the tokens before falling back to the cookies.

Below is the sample code for the middleware:

public class TokenManagementMiddleware
{
    private readonly RequestDelegate _next;

    public TokenManagementMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var accessToken = context.Request.Cookies["access_token"];
        var refreshToken = context.Request.Cookies["refresh_token"];

        if (IsAccessTokenExpired(accessToken))
        {
            var tokens = RefreshTokens(refreshToken);
            context.Response.Cookies.Append("access_token", tokens.AccessToken, new CookieOptions { Expires = DateTimeOffset.UtcNow.AddMinutes(10) });
            context.Response.Cookies.Append("refresh_token", tokens.RefreshToken, new CookieOptions { Expires = DateTimeOffset.UtcNow.AddMinutes(30) });

            // Store in HttpContext.Items for immediate use
            context.Items["access_token"] = tokens.AccessToken;
        }

        await _next(context);
    }

    private bool IsAccessTokenExpired(string accessToken)
    {
        // Code to check if the token has expired
    }

    private (string AccessToken, string RefreshToken) RefreshTokens(string refreshToken)
    {
        // Refresh token code
    }
}

Startup.cs:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseMiddleware<TokenManagementMiddleware>();
    .......
    ........
  
}

In your controller or wherever you need to access the tokens, first check HttpContext.Items:

var accessToken = HttpContext.Items["access_token"] as string ?? HttpContext.Request.Cookies["access_token"];