Cookies' update from response delayed in future

1.4k views Asked by At

I've encountered an odd issue with ngCookies service. Mainly, after receiving a response from my /api/auth/login/ endpoint, with headers:

Set-Cookie  csrftoken=gxCld8gEga71MuQPQbjDujDBvR4HwPvu; expires=Sun, 28-Dec-2014 15:31:38 GMT; Max-Age=31449600; Path=/

the $cookies['csrftoken'] is updated after unspecified amount of time. This fact has been documented in the docs:

Only a simple Object is exposed and by adding or removing properties to/from this object, new cookies are created/deleted at the end of current $eval.

Knowing that, I've resorted to the use of $timeout to hopefully delay the evaluation of my code to after the aforementioned $eval.

Ended up with the following (CoffeeScript):

login = () ->
    deferred = $q.defer()

    $http.post('/api/accounts/login/', data)
    .success((data) ->
        args = arguments
        $timeout(() ->
            do_fancy_stuff()
            deferred.resolve.apply(deferred, args)
        )
        return
    ).error(() ->
        args = arguments
        $timeout(() ->
            deferred.reject.apply(deferred, args)
        )
        return
    )

    promise = deferred.promise
    promise.success = promise.then
    promise.error = promise.catch
    promise

But the code above still suffers from the issue. Cookies are updated with the value from response way after $timeout kicks in.

After adding console.log('cookies push', $browser.cookies().csrftoken, cookies.csrftoken); here (after the if statement). I've ended up with something like this:

enter image description here

As you can see, the tokens were equal after 7 prints.

The yhQqT6KOfSKYCNB3Ag4sEPllMgkLrVj1 token comes from previous session. I'm testing logging out and in to the app without refreshing the page. The Setting X-CSRFToken is called directly in my do_fancy_stuff() function (no async things, just bare $cookies['csrftoken'] access).

Also the use of $q is required to provide $http-like promise as return value (there would be no $q if cookies were working fine).

2

There are 2 answers

0
Seth M. On

The solution I chose to use based on the information found here and here. Tells me that the $cookies will attempt to refresh every 100ms. So with this information in mind you can add a $timeout to any request that needs to use the response cookies.

        $http.post(url, tokens)
            .success(function(result, status, headers, config) { // sign in successful
                $timeout(function() { /* do stuff with $cookies here. */ }, 100);
            })
            .error(function(data, status, headers, config) {
            });
0
chinmayan On

$cookies service has a pollerfn that copies all cookies from the $browser, and this poller periodically executes every 100ms.So better to put a $timeout for 150ms for avoiding the edge cases.