lemon
lemon

Reputation: 187

How to add HttpOnly cookie to axios request

I am implementing refreshToken in my ASP.NET CORE WEB API + React application and I can't figure out how to send this token back to my API with another request.

My API adds refreshToken as HttpOnly cookie to requests.

  1. Api endpoint
        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> GenerateToken([FromForm]LoginModel model)
        {
            var result = await _userService.GetTokenAsync(model);
            SetRefreshTokenInCookie(result.RefreshToken);
            return Ok(result);
        }
  1. Adding refresh token to response
        private void SetRefreshTokenInCookie(string refreshToken)
        {
            var cookieOptions = new CookieOptions
            {
                HttpOnly = true,
                Expires = DateTime.UtcNow.AddDays(10)
            };
            Response.Cookies.Append("refreshToken", refreshToken, cookieOptions);
        }

I can see cookie with refreshToken while browsing 'Network' in my chrome dev tools. enter image description here

But there is no cookie in 'Application'

enter image description here

And there is no cookie in next request as well.

enter image description here

I am using Axios to send requests. How can I get that refreshToken in my backend?

Upvotes: 9

Views: 20203

Answers (3)

Krzysztof Juszcze
Krzysztof Juszcze

Reputation: 467

In my case, the API and UI had different URLs and I had to add two additional settings to CookieOptions:

private void SetRefreshTokenCookie(string token)
{
    var cookieOptions = new CookieOptions
    {
        HttpOnly = true,
        Expires = DateTime.UtcNow.AddDays(1),
        SameSite=SameSiteMode.None,
        Secure=true
    };
    Response.Cookies.Append("refreshToken", token, cookieOptions);
}

SameSiteMode.None inform that cookie is set by respons from different origin. This option indicates that you need Secure=true. This opions means that

A cookie with the Secure attribute is only sent to the server with an encrypted request over the HTTPS protocol.

like was described here: developer.mozilla.org

After that changes, you will have set a cookie in the browser in the Application tab

Upvotes: 2

Alan
Alan

Reputation: 10145

You need to add withCredentials. With this flag, it will send to the server all HttpOnly cookies.

axios("http://example.com/api/things/", {
  method: "post",
  data: someJsonData,
  withCredentials: true
})

Upvotes: 11

lemon
lemon

Reputation: 187

It turns out that was CORS issue. Setting this in my Startup.cs file worked like a charm.

            services.AddCors(options =>
            {
                options.AddPolicy("CORSAllowLocalHost3000",
                  builder =>
                  builder.WithOrigins("http://localhost:3000")
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials() // <<< this is required for cookies to be set on the client - sets the 'Access-Control-Allow-Credentials' to true
                 );
            });

Upvotes: 2

Related Questions