简体   繁体   中英

Cannot create httponly cookie containing jwt in ASP.NET Core and React

I'm trying to implement an authentication scheme in my app. The controller, more specifically the method, responsible for checking user's credentials and generating jwt which it has to put into the httponly cookie afterward looks as follows

    [HttpPost]
    [Route("authenticate")]
    public async Task<IActionResult> Authenticate([FromBody] User user)
    {
        var response = await _repository.User.Authenticate(user.Login, user.Password);
        if (!response) return Forbid();

        var claims = new List<Claim>
        {
            new Claim("value1", user.Login)
        };
        string token = _jwtService.GenerateJwt(claims);

        HttpContext.Response.Cookies.Append(
            "SESSION_TOKEN",
            "Bearer " + token,
            new CookieOptions
            {
                Expires = DateTime.Now.AddDays(7),
                HttpOnly = true,
                Secure = false
            });

        return Ok();
    }

I tested this method in Postman - everything works gently and correctly in there. The cookie is being created as well. Moreover, recently I created an app using Angular where I was using the same authentication method, but with Angular's HTTP module the cookie was being created all the time. Here is what that method looks like in my React app with the usage of Axios

export const authenticate = async (login, password) => {
 return await axiosLocal.post('/api/auth/authenticate',
    {login, password}).then(response => {
    return response.status === 200;
 }, () => {
    return false;
});

Everything I'm getting in response trying to log in is response code 200. I'm pretty sure it's something about Axios's settings. Also if someone's curios the variable "axiosLocal" contains the baseURL to the API.

- Update 1 Ok. If I'm not mistaken in order to set a cookie from the response I have to send all the requests with { withCredentials: true } option. But when I'm trying to do that the request is being blocked by CORS, although I had already set a cors policy which has to allow processing requests from any origin like that

app.UseCors(builder => builder.AllowAnyHeader()
            .AllowAnyMethod()
            .AllowAnyOrigin()
            .AllowCredentials());

Finally solved. Passing .SetIsOriginAllowed(host => true) instead of .AllowAnyOrigin() to CORS settings with { withCredentials: true } as an option in Axios request helped me.

I just had the same issue. I fixed it.

Problem:

  • In browsers, the httpOnly cookie was received and not returned to the server

  • In Postman working

// Problemable server code for settings httpOnly cookie
Response.Cookies.Append("refreshToken", refreshToken.Token, new CookieOptions
{
   HttpOnly = true,
   Expires = DateTime.UtcNow.AddDays(7),             
});

Solution:

  • On the server .AllowCredentials() and .SetOriginAllowed(host => true) or .WithOrigins("https://localhost:3000")

  • On the client (react, axios) withCredentials:true in the headers

If still not working open the Network tab in DevTools in Chrome(current v.91.0.4472.124), select the failed request and when you put the mouse over the yellow triangle you can see very detailed information why the cookie is blocked.

开发工具/网络/请求名称/ResponseHeaders


 // End server code for setting httpOnly cookie after following the DevTools warnings
Response.Cookies.Append("refreshToken", refreshToken.Token, new CookieOptions
{
      HttpOnly = true,
      Expires = DateTime.UtcNow.AddDays(7),
      IsEssential=true,
      SameSite=SameSiteMode.None,
      Secure=true,
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM