websanova / vue-auth

A simple light-weight authentication library for Vue.js
MIT License
2.36k stars 379 forks source link

How to set token expiration as refreshData interval #682

Open darkons opened 2 years ago

darkons commented 2 years ago

First of all, thank you for this awesome auth package!

I did the following implementation for a based Laravel Passport API:

plugins/auth.js

import { createAuth } from '@websanova/vue-auth/src/v3'
import axios from '@/plugins/axios'
import router from '@/router'
import passportDriver from '@/plugins/auth/drivers/passport'
import driverHttpAxios from '@websanova/vue-auth/src/drivers/http/axios.1.x'
import driverRouterVueRouter from '@websanova/vue-auth/src/drivers/router/vue-router.2.x'

export default (app) => {
  app.use(
    createAuth({
      plugins: {
        http: axios,
        router: router,
      },
      drivers: {
        http: driverHttpAxios,
        auth: passportDriver,
        router: driverRouterVueRouter,
      },
      options: {
        loginData: {
          url: '/v1/auth/login',
          method: 'POST',
          redirect: '/owners',
          fetchUser: true,
          staySignedIn: true,
        },
        logoutData: {
          url: '/v1/auth/logout',
          method: 'DELETE',
          redirect: '/',
          makeRequest: true,
        },
        fetchData: { url: '/v1/user/profile', method: 'GET', enabled: true },
        refreshData: {
          url: '/v1/auth/refresh',
          method: 'POST',
          enabled: true,
          interval: 60,
        },
        rolesKey: 'roles',
        tokenDefaultKey: 'access_token',
        refreshTokenKey: 'refresh_token',
        tokenExpiresKey: 'expires_in',
      },
    })
  )
}

login response

{
    "token_type": "Bearer",
    "expires_in": 2592000,
    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI.........",
    "refresh_token": "def502001ba0735c080bd9943fff4763........."
}

plugins/auth/drivers/passport.js

export default {
  request: function (req, token) {
    // If refresh, add refresh_token to request data
    if (req.url === this.options.refreshData.url) {
      req.data = { refresh_token: this.token(this.options.refreshTokenKey) }
    }

    this.drivers.http.setHeaders.call(this, req, {
      Authorization: 'Bearer ' + token,
    })
  },

  response: function (res) {
    const resData = res.data || {}

    // Store refresh_token if present
    this.token(
      this.options.refreshTokenKey,
      resData[this.options.refreshTokenKey]
    )

    // Return access_token (auto stored)
    return resData[this.options.tokenDefaultKey]
  },
}

The question is, how can I set refreshData interval value depending on login response expires_in value? With this approach auth package will refresh token automatically based on token "true" expiration time.

Thank you in advance!

websanova commented 2 years ago

In this case you would need to disable refresh and do it manually.

So in your options setup set the enabled flag in refreshData to false.

        refreshData: {
          url: '/v1/auth/refresh',
          method: 'POST',
          enabled: false,
          interval: 60,
        },

Then on login just put your own timer

setInterval(function () {
    this.$auth.refresh();
}, 3000);

Where 3000 is whatever value you want of course.