[英]Unable to get item from localstorage when vue page is mounted using pinia store
我正在使用 vue 3 composition api 和 pinia store 构建应用程序。 当用户登录成功时,我将令牌存储在localStorage
中,然后将用户推送到仪表板。 在安装仪表板视图时,我想使用商店数据,该数据旨在调用仅授权的端点,因此我创建了一个 pinia 商店profile
import { defineStore } from "pinia";
import http from '../http-common';
export const useProfile = defineStore("profile", {
state: () => {
return {
userSummary: {},
error: null
};
},
getters: {
async userSummary() {
try {
const res = await http.get('dashboard');
this.userSummary = res.data.data;
} catch (error) {
this.error = error;
}
}
}
});
在http-common.js
中,我使用 axios 并从 localStorage 获取存储的令牌并将其用于 api 调用
import axios from "axios";
export default axios.create({
baseURL: "https://api-domain/api/",
headers: {
"Authorization": `Bearer ${localStorage.getItem('accessToken')}`
}
});
登录accessToken
他存储在 localStorage 中的位置
const loginUser = async () => {
try {
const res = await axios.post(
"https://api-domain/api/login",
signin.value,
{
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
}
);
localStorage.setItem("accessToken", res.data.data.accessToken);
localStorage.setItem("verified", res.data.data.verified);
// redirect home
router.push({ name: "dashboard" });
} catch (error) {
error = error.response.data.message;
alert(error);
}
};
在仪表板视图中,我正在使用配置文件存储
<script setup>
import {onMounted} from "vue";
import {useProfile} from "../stores/profile";
const profile = useProfile();
onMounted(() => {
profile.userSummary;
});
</script>
问题是,当仪表板视图安装时,api调用失败,我可以在 null Authorization: Bearer null
中看到请求授权。 从开发人员工具中检查,我可以看到accessToken
实际上是设置的,而不是空的。
我该如何解决这个问题?
您期望 localStorage 在这里是被动的:
headers: {
"Authorization": `Bearer ${localStorage.getItem('accessToken')}`
}
但事实并非如此。 设置为header.Authorization
config 标头的字符串。稍后,当您覆盖本地存储中令牌的值时,授权不会神奇地改变。
这是您当前正在执行的操作:
您正在通过从本地存储读取accessToken
来配置axios
(尚未进行身份验证调用)。 即使本地存储中有一个令牌,它也来自上一个会话,因此可能会过期。
您登录用户,并将令牌设置为本地存储。
您继续使用在步骤 1 中配置的axios
实例。
您可能想使用 axios拦截器。 这是因为拦截器是在发出/接收请求/响应时运行的,而不是在配置 axios 时运行。
您需要一个请求拦截器:如果当前调用转到您的 API 并且不是身份验证请求,则您从某个存储(通常是身份验证存储)中读取令牌。
.config
创建的新 axios 请求来解决存储的承诺。 通过这样做,您将请求重新排队,这使其再次通过请求拦截器。 他们现在将通过,因为您有一个令牌,他们将获得附加的身份验证标头。 您还需要一个响应拦截器:如果当前调用返回401
(这意味着令牌刚刚过期),
显然,如果错误有不同的代码(除了401
),你需要抛出它:它是合法的。
差不多就是这样。
但是,它确实有一个小问题:如果您的身份验证被破坏,并且它没有提供有效的令牌,而是提供了不起作用的令牌,您的应用程序将在获得错误的令牌后继续尝试进行身份验证,这将再次失败,然后是一个新的将在无限循环中发出身份验证请求。
要解决此问题,您可能希望对身份验证失败设置一个计数器。 我没有将其包括在上面,因为我认为尽可能清楚地呈现主要的身份验证逻辑很重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.