【发布时间】:2019-06-26 23:43:30
【问题描述】:
我正在使用带有 DRF 的 Django JWT 和带有 axios 的 Vue Js。当用户登录时,我检索令牌并将其存储在我已验证可以工作的本地存储中。然后我重定向到一个新页面,在那里我发出另一个请求以获取数据。每次我重定向到这个页面时,我都会得到一个 401 未授权,当我刷新页面时它工作正常。在发出第二个请求之前,我检查以确保令牌已存储。我试图在创建的钩子中获取重定向页面上的数据。我还创建了一个 axios 实例来处理标头并使用基本路由,然后将其导入到需要的文件中,我不确定这是否与它有关。这也仅在令牌过期并且您尝试检索新令牌时发生。我应该刷新令牌而不是尝试获取新令牌吗?
Axios 实例
import axios from 'axios'
export default axios.create({
baseURL: `http://127.0.0.1:8000/`,
headers: {
'Content-Type': 'application/json',
Authorization: 'JWT ' + localStorage.getItem('token')
},
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFToken',
withCredentials: true
})
编辑
api.js
import axios from 'axios'
export default axios.create({
baseURL: `http://127.0.0.1:8000/`,
headers: {
'Content-Type': 'application/json',
Authorization: 'JWT ' + localStorage.getItem('token')
},
xsrfCookieName: 'csrftoken',
xsrfHeaderName: 'X-CSRFToken',
withCredentials: true
})
AppLogin.vue
点击登录按钮触发确认
confirm: function() {
API.post("accounts/login/", {
email: this.email,
password: this.password,
})
.then(result => {
console.log(result.data.token);
this.token = result.data.token;
localStorage.setItem("token", this.token);
this.getUserInfo()
})
.catch(error => {
console.log(error);
});
},
getUserInfo: function(){
axios.get("http://127.0.0.1:8000/userinfo/get/", {
headers: {
'Content-Type': 'application/json',
Authorization: 'JWT ' + this.token
}
})
.then(response => {
console.log(response.data.pos);
var pos = response.data.pos;
this.reroute(pos);
})
.catch(error => {
console.log(error);
});
},
reroute(pos) {
if (pos == "owner") {
this.$router.push({ path: "/bizhome" });
} else {
this.$router.push({ path: "/" });
}
}
BizHome.vue
这是登录成功后重定向到的页面
created: function() {
this.getLocations();
},
methods: {
getLocations() {
API.get("business/")
.then(response => {
this.biz = response.data;
})
.catch(error => {
console.log(error);
});
API.get("locations/")
.then(response => {
this.bizLocations = response.data;
})
.catch(error => {
console.log(error);
});
},
}
解决方案
使用我从下面的 YuuwakU 获得的一些建议,我将标头直接添加到 getLocations 方法中的 get 调用中,以覆盖 axios 实例标头。似乎在实例中更新令牌之前加载的新页面。但是,此解决方案的一个缺点是我现在必须将标头直接添加到我进行的所有调用中。实例中的标头永远不会更新。我确实将API.defaults.headers.common['Authorization'] = 'JWT ' + result.data.token; 添加到了成功检索令牌的confirm 方法中,该令牌应该已经更新了实例的令牌。这对我不起作用,如果有人有任何想法,我有兴趣听听他们的意见
编辑 2
我确实弄清楚了为什么 axios 实例没有更新它,因为我试图从 api.js 中的本地存储中获取令牌并且它覆盖了它。现在它可以工作了,但令牌不是持久的,所以这也不理想。如果我找到更好的解决方案,我会更新。
最终更新
我终于想出了一个好的解决方案。我从 api.js 中的 axios 实例中删除了授权标头,然后从所有 axios 调用中删除了所有标头。在成功登录的确认方法中,我添加了前面提到的这一行API.defaults.headers.common['Authorization'] = 'JWT ' + result.data.token;,并将令牌添加到本地存储。我有一个在页面加载之前运行的验证令牌方法。在我发出发布请求以验证我添加的令牌之前的那个方法 API.defaults.headers.common['Authorization'] = 'JWT ' + localstorage.getItem('token'); 。这允许用户离开站点并返回并在有效的情况下仍然使用令牌,并且不需要在每次调用时设置标头。
【问题讨论】:
标签: django-rest-framework jwt axios