websanova / vue-auth

A simple light-weight authentication library for Vue.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cookie with Refresh Interval On Same Page

jawa-the-hutt opened this issue · comments

Currently, when the refresh interval comes up, it will go out to my refresh endpoint and bring back the token as needed. I'm putting the token into a Cookie.

When you navigate to a new page, it run the refresh method successfully and reset the cookie's expire time appropriately based on what I have in the plugin's options. However, if I stay on the same page and let the refresh interval run, then the cookie's expire time is never updated.

In theory, I can have the refresh interval run every 1 minute for the 20 minute token expiration window and it will never update the cookie. At the end of the 20 minutes, the cookie will expire and the browser will delete it automatically. This means that in certain circumstances, I'm sent back to the login route when all along, it should have been updating the token via the refresh method.

So, my question is can this situation be handled by the plugin?

FWIW, right now, I'm getting around this by manually resetting the cookie with a custom http driver that when it comes back from the refresh endpoint, it will reset the cookie back up. Not ideal, so I'd like to see if this can be addressed in the plugin or if it's already addressed, find out how I should handle this.

I guess this situation would also apply to the auth_stay_signed_in cookie if it's value is true. It's expiration value is never updated, so it will expire and self delete as well.

Not sure, I hundred percent follow, but if you are doing a manual update of some cookie alongside the plugin then ya it would be best to just do a custom auth driver.

For instance:

https://github.com/websanova/vue-auth/blob/master/src/drivers/auth/basic.js

There you could just update the response to take that token and store it in your alternative storage. And likewise for the request function you could check that alternative or just use the given token.

Right now I'm doing a manual update of the cookie as I didn't find a way to have the plugin do something like this on it's own.

To be clear, I'm not storing anything in custom storage. I'm using the built in Cookie feature of the plugin.

  1. User logs in
  2. API sends back an auth token.
  3. Plugin stores token in Cookie based on the options configured.
  4. Refresh Interval happens and the refresh API endpoint is hit.
  5. API sends back updated auth token. This token has an updated Expire time inside it.

What happens at this point is the question I think. When the cookie is created in step 3 above, it sets an Expire time based on the Cookie options config. However, when the refresh happens, the expire time of the cookie is not being updated with a new expire time. So my question is should this expire time of the cookie be updated by the plugin during the in-page refresh interval or by myself as I'm currently doing now?

Hopefully that makes things more clear?

Hmm, I see, so that's something to dig into.

Can you dump the library into your project locally and put a console.log(args) above the line in this file:

https://github.com/websanova/vue-auth/blob/master/src/lib/token.js

        if (
            ts[i] === 'cookie' &&
            __utils.isCookieStorage()
        ) {
            console.log(args); // let's see what's being fed in here...
            return __cookie[action].apply(this, args);
        }

We can then compare this between regular request and the refresh request.

Here's the logging for sign-in:

['auth_remember']
['auth_stay_signed_in', 'true', false]
['auth_token_impersonate']
['auth_token_default']
['auth_stay_signed_in']
['auth_token_impersonate']
['auth_token_default', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjQ3N…MuQWNjb3VudHMuVXBkYXRlIl0sImV4cCI6MTYzODMwMDE0Nn0...', false]

Here's the logging for the refresh:

['auth_token_impersonate']
['auth_token_default']
['auth_token_impersonate']
['auth_token_default']
['auth_stay_signed_in']
['auth_token_impersonate']
['auth_token_default', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjQ3N…MuQWNjb3VudHMuVXBkYXRlIl0sImV4cCI6MTYzODMwMDI1MH0...', false]

yes...the token looks funky there. I abbreviated it.

@jawa-the-hutt hmm, ya so we follow that call here:

https://github.com/websanova/vue-auth/blob/master/src/lib/cookie.js#L47

Could be some potential issue here with how the cookie is set the second time.

Maybe further investigate with a console.log(cookie) before the cookie is set here:

https://github.com/websanova/vue-auth/blob/master/src/lib/cookie.js#L29

That should probably expose what's going on between those two.

It's basically setting the Expires value to whatever it is set the first time.

I think what may be going on in my specific case is that my Expires value is a function that is being called. So something like this:

cookie: {
  Path: '/',
  Secure: true,
  Expires: expiresAt(),
  SameSite: 'Strict'
},

where I am doing a manual calculation of the value based on other factors in play in my environment. I guess my expectation was that the function would be called each time the cookie is set, but it doesn't appear that it works this way internally and I'm not sure if that is something that you necessarily need to fix or not.

I've tried debugging the plugin's code to see exactly where things might be going amiss but I cannot figure it out.

TLDR: it would be nice if the Expires param could take a function and then each time it processed the setCookie, it would run the function again, so consider this a feature request.

Hmm, yea, very likely something going on with that then.

If you look at this line:

https://github.com/websanova/vue-auth/blob/master/src/lib/cookie.js#L38

It's by default setting a relative "numeric" value. Because it's a string it's catching the first if block and getting stuck on that default until a page refresh.

Two solutions I see here:

  1. Just pass a numeric value so that's it's relative (the default there is 2 weeks I believe).

  2. If it's dynamic we'll have to add a block there to first check for a typeof val === function and do it that way. And the cookie object could then be:

cookie: {
  Path: '/',
  Secure: true,
  Expires: expiresAt,
  SameSite: 'Strict'
},

I guess 2. I'll add anyway eventually, but I'm quite busy with things atm. And will be in the process soon, of updating docs, etc, so I'm kind of just holding off on any changes until I get the docs in order.

But feel free to submit a pull request for the latter.

Added a PR for this. Ended up being pretty simple. Thanks for pointing in the right direction