首页 > 解决方案 > 自动登录完成后请求vuejs axios

问题描述

自动登录成功后如何执行所有其他请求。代码示例。

  axios.get('personal/' + this.$store.state.username + '/config/', {headers: { Authorization: 'Token ' + this.$store.state.idToken }})

有时接收用户数据(用户名和 ID)的请求没有时间传递并提交到状态,并且我收到用户名在状态下为空的错误。

我已经通过添加登录函数将用户名和 ID 保存在本地存储中解决了这个问题,并且在尝试自动登录之后我有下一个代码:

tryAutoLogin ({ commit, dispatch }) {
      const token = localStorage.getItem('token')
      if (!token) {
        return
      } else {
        commit('getToken', {
          key: token
        })
        const userId = localStorage.getItem('userId')
        const username = localStorage.getItem('username')
        if (!userId || !username) {
          dispatch('getUser')
        } else {
          commit('getUserData', {
            id: userId,
            username: username.username
          })
        }
      }

这种方式可以吗?或者有任何方法可以停止对 api 的任何请求,直到dispatch('getUser')成功通过。代码示例getUser

getUser ({ commit, state }) {
      if (!state.idToken) {
        return
      }
      axios.get('rest-auth/user/', {headers: { Authorization: 'Token ' + state.idToken }})
        .then(res => {
          localStorage.setItem('username', res.data.username)
          localStorage.setItem('userId', res.data.pk)
          commit('getUserData', {
            id: res.data.pk,
            username: res.data.username
          })
        })
    },

请不要严格,我是 FE vue js 的新手:)

标签: vuejs2vuex

解决方案


首先,让 getter、action、mutations 和 state 的名称更加简洁明了(例如 getUser 表示 getter,setUser 表示 action)。

我建议创建一个单独的身份验证模块(将所有身份验证逻辑放在此模块中)并在 Vuex 操作或应用程序中的某个位置使用它。

此类模块应通过 Vuex 的 getter、setter 和操作(例如,获取和设置当前用户身份验证状态)与 Store 交互。它使认证更加封装和清晰。

通过这种方式,您将能够从任何应用程序组件调用此模块的方法并等待结果。

在下面的代码中 ( http_auth.js)this.$auth是单独的身份验证模块,可以在 Vuex 中设置用户状态并获取当前状态。它还使用 localStorage 检查保存的令牌(用户数据)并尝试使用保存的令牌进行授权(tryAutoLogin在您的情况下)。失败时,它会重定向到登录页面。

...
methods: {
  async loadInitialData () {
    if (await this.$auth.init()) {
      axios.get('initial-data-url').then(res => ...)
    }
  }
},
created () {
  this.loadInitialData()
}
...

Auth 方法是基于 Promise 的,所以你可以等待之前解决或拒绝。

如果您只想使用 Vuex-only 解决方案,您应该使用操作来调用 API 请求并将它们包装在 Promises 中。您还可以在其他操作中分派一些操作(例如,尝试在基本登录操作中使用保存的令牌登录)。示例代码(Vuex 操作):

LOAD_SOME_DATA ({ commit, state, getters }, id) {
    return new Promise((resolve, reject) => {
      if (!id) {
        router.push('/')
        return reject('Invalid ID passed.')
      }
      return axios.get(getters.GET_SOME_URL + id).then(response => {
        commit('PUSH_SOME_DATA', response.data)
        return store.dispatch('PROCESS_SOME_DATA').then(result => {
          return resolve(response)
        }, error => {
          console.error('Error loading some data: ', error)
          return reject(error)
        })
      }, error => {
        router.push('/')
        return reject(error)
      })
    })
  }

上面我们封装了promise basic api-call( axios.get(getters.GET_SOME_URL + id)),然后处理接收到的数据( PROCESS_SOME_DATA)。然后我们可以在路由器中使用它,例如(或应用程序的任何其他部分):

store.dispatch('LOAD_SOME_DATA', to.params.id).then(result => ...)

推荐阅读