如何在自动登录wass传递后执行所有其他请求。代码示例。
axios.get('personal/' + this.$store.state.username + '/config/', {headers: { Authorization: 'Token ' + this.$store.state.idToken }})
有时接收用户数据(用户名和id)的请求没有时间传递并提交状态,并且我收到一个错误,即状态为用户名为null。
我已经通过在login func中添加以在localstorage中保存用户名和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
})
})
},
Plz,不要严格我是FE vue js的新人:)
答案 0 :(得分:0)
首先,让getter,actions,mutation和state的名称更清晰明了(例如getUser for getters和setUser for action)。
我建议创建一个单独的 auth模块(将所有auth逻辑放在此模块中)并在Vuex操作或应用程序中的某个位置使用它。
此类模块应通过Vuex getter,setter和actions(例如,获取和设置当前用户身份验证状态)与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的解决方案,则应使用操作来调用API请求并将其包装在Promise中。您也可以在其他内部调度一些操作(例如,尝试使用基本登录操作中的已保存令牌登录)。 示例代码(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基本api-call(axios.get(getters.GET_SOME_URL + id)
)换行,然后处理收到的数据(PROCESS_SOME_DATA
)。
然后我们可以在路由器中使用它,例如(或app的任何其他部分):
store.dispatch('LOAD_SOME_DATA', to.params.id).then(result => ...)