Search code examples
c#asp.net-corecookies.net-coreflurl

Missing cookies during login using Flurl


Somehow some of the cookies are missing when I'm trying to login to a web service. Three parts of the cookie are missing, specifically the token and refresh-token. However when I try logging in using Postman I get all parts of the cookie. Which is very strange, below you can see my code for logging in to the service using Flurl.

private async Task<IFlurlClient> GetClientAsync()
{
    var client = new FlurlClient(BaseUrl).EnableCookies();
    var login = await client.Request("/Account/LogOn")
                            .AllowAnyHttpStatus()
                            .PostUrlEncodedAsync(new { Login = credentials.Username, credentials.Password});

    if (!login.IsSuccessStatusCode) throw new ResponseException("Login failed");
    return client;
}

See screenshot for the cookies I can see when debugging.

image of debug cookies

Next we can see which cookies I can see when I use Postman.

image of postman cookies

I need all 7 cookies for subsequent calls to the service. Any idea on what I might be doing wrong or what could be missing?

When using Postman all I do is a simple POST with form-data using the credentials I have. Both the calls, Postman and Flurl, succeed with a status code 200 OK, all that differs are the received cookie values.


Solution

  • Thanks to Todd I solved my issue by updating to Flurl 3.0 and updated my code. See below for the new and improved version using CookieSession.

    private async Task<CookieJar> GetCookiesAsync()
    {
        using var session = new CookieSession(Endpoint);
        var data = new {credentials.Username, credentials.Password};
    
        var login = await session.Request("/login").AllowAnyHttpStatus().PostUrlEncodedAsync(data);
        return login.ResponseMessage.IsSuccessStatusCode ? session.Cookies : null;
    }
    
    ...
    
    var cookies = await GetCookiesAsync();
    if (cookies == null) return false;
    
    var test = await Endpoint.AppendPathSegment("/test")
                             .WithCookies(cookies)
                             .AllowAnyHttpStatus()
                             .PostAsync(null);
    
    var success = test.ResponseMessage.IsSuccessStatusCode;
    

    Using this I could pass the cookies received when logging in to any subsequent calls and everything worked just as it should.

    Edit:

    Updated code again to use Todds suggestion, see below.

    private async Task<CookieSession> CreateSessionAsync()
    {
        using var session = new CookieSession(Endpoint);   
        var data = new {credentials.Username, credentials.Password};
    
        var login = await session.Request("/login").AllowAnyHttpStatus().PostUrlEncodedAsync(data);
        return login.ResponseMessage.IsSuccessStatusCode ? session : null;
    }
    
    var session = await CreateSessionAsync();
    if (session == null) return false;
    
    var test = await session.Request("/test")
                            .AllowAnyHttpStatus()
                            .PostJsonAsync(new {});
    
    return test.ResponseMessage.IsSuccessStatusCode;
    

    Once again, thank you so much Todd! This solution is working wonders in production at the moment.