auth-module icon indicating copy to clipboard operation
auth-module copied to clipboard

Refresh scheme doesn't automatically refresh token when token expires

Open sts-ryan-holton opened this issue 2 years ago • 9 comments

Version

module: 5.0.0-1624817847.21691f1 nuxt: 2.15.8

Nuxt configuration

mode:

  • [x] universal
  • [ ] spa

Nuxt configuration

auth: {
  redirect: {
    login: '/account/login/',
    logout: '/account/login/',
    callback: '/account/login/',
    home: '/account/beams/'
  },
  strategies: {
    local: {
      scheme: 'refresh',
      refreshToken: {
        property: 'token',
        data: 'token'
       },
      endpoints: {
        login: { url: '/api/account/login', method: 'post', propertyName: 'token' },
        refresh: { url: '/api/account/refresh', method: 'post', },
        logout: { url: '/api/account/logout', method: 'post' },
        user: { url: '/api/account', method: 'get', propertyName: 'user' }
      }
    }
  }
},

Additional information

Checklist

  • [x] I have tested with the latest Nuxt version and the issue still occurs
  • [x] I have tested with the latest module version and the issue still occurs
  • [x] I have searched the issue tracker and this issue hasn't been reported yet

Steps to reproduce

What is expected?

When a user's token expires and refresh scheme is implemented, a user shouldn't be logged out and redirected back to the login screen, the refresh token should be used to obtain a new token and the transition should be seamless allowing any authenticated route to continue to work.

What is actually happening?

In my Nuxt project with the Auth module I've implemented the refresh scheme, however, when my token expires I don't see any request in my network being made to the refresh route after my token expires and I navigate to a protected page via the auth middleware.

I expect I'm missing some simple configuration?

My current token has an expiry of 1 minute for testing, and my refresh token has an expiry of 14 days for testing.

However, when adding:

  • scheme: 'refresh'
  • refresh: { url: '/api/account/refresh', method: 'post', }

the functionality appears to not be fetching my user and automatically logging me in.

My /api/account/refresh endpoint in my API returns the following:

{
  token: 'my refresh token',
  token_type: 'bearer',
  expired_in: 5000
}

My /api/account/login endpoint in my API returns the following:

{
  token: 'my token',
  token_type: 'bearer',
  expired_in: 1000
}

What am I missing?

sts-ryan-holton avatar Aug 18 '21 18:08 sts-ryan-holton

Is there any update on this?

sts-ryan-holton avatar Aug 22 '21 12:08 sts-ryan-holton

Also encountering this issue, were you able to find a solution?

Destaq avatar Aug 29 '21 11:08 Destaq

@Destaq in my set up, I'm using the tymon/jwt-auth package for Laravel, turns out by switching to the Laravel JWT provider in the auth-module, and exposing my refresh endpoint it works.

sts-ryan-holton avatar Aug 30 '21 08:08 sts-ryan-holton

Hmmm, I guess that means there's an issue within the refresh scheme source code. Thanks for sharing; unfortunately I'm using Flask so going to have to keep digging.

Destaq avatar Aug 30 '21 10:08 Destaq

I have the same problem. After authorization, if you press F5, authorization disappears, although I see a valid token in the storage. Here is my config auth: { scopeKey: 'user_type', rewriteRedirects: true, strategies: { local: { scheme: 'refresh', localStorage: { prefix: 'auth.' }, token: { prefix: 'access_token.', property: 'access_token', maxAge: 1800, type: 'Bearer' }, refreshToken: { prefix: 'refresh_token.', property: 'refresh_token', data: 'refresh_token', maxAge: 86400 }, user: { property: 'user', autoFetch: true }, endpoints: { login: { url: '/login', method: 'post'}, refresh: { url: '/token/refresh/', method: 'post' }, user: { url: '/user', method: 'get' } }, } }, redirect: { home: '/redirect', }, cookie: { options: { maxAge: 86400 // 24 hours } }, resetOnError: true, },

alimuradov avatar Aug 31 '21 05:08 alimuradov

Hey @Destaq, I have a Nuxt / Django project with JWT and it works for me with the djangorestframework-simplejwt package. Maybe you can get some inspiration there.

Here's my Nuxt config for the auth module:

  auth: {
    cookie: {
      options: {
        secure: process.env.NODE_ENV === 'production', // Enable in production only.
        sameSite: 'lax',
      },
    },
    redirect: {
      login: '/login',
      logout: '/login',
      callback: '/login',
      home: '/write',
    },
    resetOnError: (error, name, endpoint) => {
      console.log('resetOnError', error, name, endpoint)
      return true
    },
    strategies: {
      local: {
        scheme: 'refresh',
        token: {
          property: 'access',
          type: 'JWT',
        },
        refreshToken: {
          property: 'refresh',
          data: 'refresh', // This is not a JWT token!
        },
        user: {
          property: false,
        },
        endpoints: {
          login: {
            url: '/auth/token/',
            method: 'post',
          },
          refresh: {
            url: '/auth/token/refresh/',
            method: 'post',
          },
          user: false,
          logout: {
            url: '/user/logout/',
            method: 'post',
          },
        },
      },
    },
  }

You have to be careful, in the case of djangorestframework-simplejwt the refresh token is not a JWT token for instance, see token type.

toniengelhardt avatar Dec 13 '21 00:12 toniengelhardt

Hey @Destaq, I have a Nuxt / Django project with JWT and it works for me with the djangorestframework-simplejwt package. Maybe you can get some inspiration there.

How did you handle parallel API calls for refresh tokens? What happens in my case is that several API calls result in a 401 response which triggers parallel API calls for refresh tokens and only the first one receives a 200. The other ones get 401 responses which make auth think that the refresh token itself has expired too.

sadeghi-aa avatar Sep 13 '22 04:09 sadeghi-aa

Wow interesting @sadeghi-aa! I'm having these random logouts sometime that I couldn't figure out, maybe it's related to that problem. Do you have any ideas on how to resolve this?

toniengelhardt avatar Sep 13 '22 09:09 toniengelhardt

Not yet. I found this open pull request about this issue. I applied it locally in my node_modules folder, but that caused some other issues that I haven't been able to solve. You could try it yourself though.

sadeghi-aa avatar Sep 13 '22 10:09 sadeghi-aa