Coder Social home page Coder Social logo

Comments (10)

elceka avatar elceka commented on June 3, 2024 1

localAuth.js

const storeItem = 'auth'

export default {
  userIsAuthenticated () {
    return !!localStorage.getItem(storeItem)
  },
  storeUserData (user) {
    localStorage.setItem(storeItem, JSON.stringify(user))
  },
  getUserData () {
    if (this.userIsAuthenticated) {
      return JSON.parse(localStorage.getItem(storeItem))
    }

    return null
  },
  removeUserData () {
    localStorage.removeItem(storeItem)
  },
  apiToken () {
    if (this.userIsAuthenticated) {
      const usrData = JSON.parse(localStorage.getItem(storeItem))

      if (!!usrData) {
        if (usrData.hasOwnProperty('api_token')) {
          return usrData.api_token
        }
      }
    }

    return null
  }
}

ApiWrapper.js

import Axios from 'axios'
import { stringify } from 'qs'
import { Vapi } from 'vuex-rest-api'
import localAuth from 'localAuth'

const apiBaseURL = 'http://localhost:8003/api/frontend'

export default class VapiWrapper {
  constructor(baseURL = null, options = {}) {
    options.baseURL = baseURL || apiBaseURL

    options.axios = Axios.create({
      paramsSerializer: function ({limit, page, sort, filter_groups, includes, mode}) {
        return stringify(
          {limit, page, sort, filter_groups, includes, mode},
          {arrayFormat: 'indices'}
        )
      }
    })

    options.axios.interceptors.request.use(
      (config) => {
        config.headers.common['Accept'] = 'application/json'

        if (localAuth.userIsAuthenticated()) {
          config.headers.common['Authentication'] = 'Bearer ' + localAuth.apiToken()
        }

        return config
      },
      (response) => {
        return response
      }
    )

    options.queryParams = true

    return new Vapi(options)
  }
}

user.js

import localAuth from 'localAuth'
import VapiWrapper from 'VapiWrapper'

const resource = new VapiWrapper(
  null,
  {
    state: {
      user: null,
      users: []
    }
  }
)
.post({
  action: 'login',
  property: 'user',
  path: () => `/login`,
  onSuccess: (state, payload) => {
    localAuth.storeUserData(payload.data)
  }
})

const store = resource.getStore()

export {resource, store}

from vuex-rest-api.

apertureless avatar apertureless commented on June 3, 2024 1

How about saving the axios instance on the vm like a plugin. You could then access it with $ and change your options.

from vuex-rest-api.

apertureless avatar apertureless commented on June 3, 2024 1

Yep. There are however various ways to to this.
You could also do some kind of dependency injection / pass the axios instance in your plugin.

import Vapi from 'vuex-rest-api'
import axios from 'axios'

Vue.use(Vapi, {axios})

You should also think about marking axios as a peerDependency . The benefit is, that you don't have conflicting versions of axios in projects.

If I install Vapi in my project, which is using another version of axios and I am making somewhere else some requests I am using my axios instance with my version. If I am using Vapi it uses another version of axios which is installed with it. This could lead to problems.

And another benefit is, that you don't need to update the package with every axios release.

from vuex-rest-api.

christianmalek avatar christianmalek commented on June 3, 2024

At the moment it's not possible to change the properties of the passed axios instance.

What would be your favorite way to implement this? I thought about adding an additional param to the onSuccess and onError functions so that you can access the Vapi axios instance.

Example:

{
  onSuccess: (state, payload, axios) => {

    axios.defaults.headers.common['Authorization'] = payload.AUTH_TOKEN;
  }
}

from vuex-rest-api.

elceka avatar elceka commented on June 3, 2024

Hi Chris,
this solution is usable, but this change Axios instance in only one Resource. How we can change Axios instance from others Resources?

For example, we have Resource with name User. User resource have action Login and some others actions. Server API for Login action don't require an authentication HTTP header. If User login action has been successfully done, we can set authentication header for Axios instance of that User Resource, and after that we can call others User actions which server API requires authentication header, that is absolutely OK.
But what, if we have more Resources and server API require authentication header for actions? We need set headers of all Axios instances of that all resources, but how?

I don't have any favorite way of implementation. But maybe we can use Axios interceptors, or adapters, ...

from vuex-rest-api.

christianmalek avatar christianmalek commented on June 3, 2024

Per default vuex-rest-api uses the global axios instance. I didn't test it yet, but shouldn't this work with the implementation example I posted above?

If you need to use a specific axios instance you could pass it to every resource constructor so that changes in the axios instance from one resource would affect the other resources as well.

Also you would have access to the axios instance. So if you want to set an adapter or interceptor it would be no problem.

from vuex-rest-api.

elceka avatar elceka commented on June 3, 2024

I use Vapi wrapper around Vapi for configuration some needed things and for configuration of Axios interceptors for handling with HTTP authentication header.
All Resources is made on that wrapper.
And then I use onSuccess function at the Resource User login action for store API token locally. Axios interceptors check local API token on each request and set HTTP header.

from vuex-rest-api.

christianmalek avatar christianmalek commented on June 3, 2024

Mhm. I like this and think I'll adapt this Wrapper to the current version so that it's backwards-compatible. But don't expect it to happen this week. I'm short on time at the moment.

BTW: PRs are welcome. :)

from vuex-rest-api.

christianmalek avatar christianmalek commented on June 3, 2024

@apertureless So you would say that the responsibility of storing the axios instance should be decoupled from vuex-rest-api and just store it in the vm? Seems reasonable to me.

from vuex-rest-api.

christianmalek avatar christianmalek commented on June 3, 2024

See #35

from vuex-rest-api.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.