2

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());
0

2 Answers 2

4

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.

DevTools/Network/request-name/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,
});
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.