Vue登录跳转首页API请求401,刷新后正常问题求助
问题分析与解决方案
问题现象
登录后通过await router.push('/')跳转到首页,首页onMounted钩子中调用axios.get('/users')返回401未授权;但刷新该页面后,请求能正常返回200并获取数据。
核心原因
- Pinia状态未同步:登录时仅把用户信息存入
localStorage,但Pinia的authStore.user并未更新,导致Axios请求拦截器无法获取有效认证令牌。 - Axios未自动携带认证信息:登录后Axios全局配置未及时更新,跳转首页的请求未携带认证令牌;而刷新页面时,会从
localStorage读取用户信息到Store,Axios拦截器能正常获取令牌,请求因此正常。
解决方案
步骤1:同步登录后的Pinia状态
修改登录函数,在存入localStorage后更新Pinia的用户状态:
async login (username, password) { const response = await axios.post('/auth/login', { username: username, password: password }); this.user = response.data; localStorage.setItem('user', JSON.stringify(this.user)); // 新增:更新Pinia的user状态 const authStore = useAuthStore(); authStore.setUser(this.user); await router.push('/'); }
对应auth.store.js添加setUser方法及初始化逻辑:
import { defineStore } from 'pinia'; export const useAuthStore = defineStore('auth', { state: () => ({ user: null }), actions: { setUser(userData) { this.user = userData; }, // 页面初始化时从localStorage恢复用户状态 initUser() { const savedUser = localStorage.getItem('user'); if (savedUser) { this.user = JSON.parse(savedUser); } } } });
步骤2:配置Axios请求拦截器自动携带令牌
创建Axios实例并配置全局拦截器,确保请求携带认证信息:
// src/utils/axios.js import axios from 'axios'; import { useAuthStore } from '../stores/auth.store.js'; const api = axios.create({ baseURL: 'http://localhost:8080' // 替换为实际后端地址 }); api.interceptors.request.use(config => { const authStore = useAuthStore(); // 假设用户信息中包含token字段,根据实际结构调整 if (authStore.user?.token) { config.headers.Authorization = `Bearer ${authStore.user.token}`; } return config; }, error => { return Promise.reject(error); }); export default api;
之后所有请求使用该实例,替换原直接调用的axios:
// 首页组件中 import api from '@/utils/axios.js'; onMounted(async () => { const response = await api.get('/users'); users.value = response.data; });
步骤3:初始化页面时恢复Store状态
在main.js中添加Store初始化逻辑,确保刷新页面时用户状态正常:
// main.js import { createApp } from 'vue'; import { createPinia } from 'pinia'; import App from './App.vue'; import router from './router.js'; import { useAuthStore } from './stores/auth.store.js'; const app = createApp(App); const pinia = createPinia(); app.use(pinia); // 初始化用户状态 const authStore = useAuthStore(); authStore.initUser(); app.use(router); app.mount('#app');
步骤4:完善路由守卫逻辑
更新路由守卫,确保Store无用户信息时先从localStorage同步:
// router.js router.beforeEach(to => { const authStore = useAuthStore(); const publicPages = ['/login']; const authRequired = !publicPages.includes(to.path); // 同步localStorage中的用户信息到Store if (!authStore.user) { const savedUser = localStorage.getItem('user'); if (savedUser) { authStore.setUser(JSON.parse(savedUser)); } } if (authRequired && !authStore.user) { return '/login'; } });
验证方法
- 登录后查看Pinia Devtools,确认
authStore.user已正确赋值。 - 跳转首页时检查Network请求头,确认包含
Authorization字段及有效令牌。 - 确认
/users请求返回200并获取到数据。
内容的提问来源于stack exchange,提问作者Othmane
相关产品推荐
相关产品推荐

