Vue3存储Bearer Token后调用API遇401未授权问题求助
登录后调用用户API返回401未授权的排查与解决
问题描述
登录逻辑中,调用登录API获取Token并存入localStorage后,立即调用用户数据API总是返回401未授权。流程执行时先输出Token,随后触发401错误。但页面刷新时,检测已存储Token的自动登录功能可正常工作。
提供的代码:
try { const response = await axios.post('user/login', { email: this.email, password: this.password }) .then( async (response) => { console.log(response.data) localStorage.setItem('token', response.data.token); const userdata = await axios.get('user/userdata'); this.$store.dispatch('user', userdata.data.userDataDTO); this.$router.push('/home'); }) .catch(err => { console.log(err) }) } catch(err){ console.log('login failed') this.failedToLogin = true; }
问题原因
核心问题是axios的请求拦截器未及时更新Token:你把Token存到localStorage后直接发起用户数据请求,但axios实例的默认请求头(比如Authorization字段)还没带上刚存储的Token,导致后端接口无法识别用户身份,返回401。而页面刷新时,自动登录逻辑会先从localStorage读取Token并设置到axios请求头中,再发起请求,所以能成功。
另外代码存在await和.then()混用的问题,这会导致逻辑混乱,也可能造成错误捕获不完整。
解决方案
方案1:配置axios全局请求拦截器(推荐)
在axios实例的全局配置中添加请求拦截器,让每次请求自动从localStorage读取Token并携带:
// 示例:在axios配置文件(如src/utils/axios.js)中 import axios from 'axios'; const axiosInstance = axios.create({ baseURL: '/api' // 替换为你的接口基础地址 }); // 请求拦截器:每次请求前自动携带Token axiosInstance.interceptors.request.use( config => { const token = localStorage.getItem('token'); if (token) { // 根据后端要求的格式调整,比如有的后端要求Bearer前缀,有的直接传Token config.headers.Authorization = `Bearer ${token}`; } return config; }, error => Promise.reject(error) ); export default axiosInstance;
然后修改登录代码,统一使用await+try/catch写法,避免混用.then():
try { // 发起登录请求 const loginRes = await axiosInstance.post('user/login', { email: this.email, password: this.password }); console.log(loginRes.data); localStorage.setItem('token', loginRes.data.token); // 此时请求拦截器会自动带上刚存储的Token const userRes = await axiosInstance.get('user/userdata'); this.$store.dispatch('user', userRes.data.userDataDTO); this.$router.push('/home'); } catch(err) { console.log(err); this.failedToLogin = true; }
方案2:手动给用户数据请求添加Token(临时方案)
如果不想配置全局拦截器,也可以在用户数据请求中手动设置请求头:
// 存储Token后,手动携带Token发起请求 const userdata = await axios.get('user/userdata', { headers: { Authorization: `Bearer ${localStorage.getItem('token')}` // 按后端要求格式调整 } });
额外优化
避免await和.then()混用,统一使用await配合try/catch处理异步逻辑,代码更清晰,错误捕获也更全面。
内容的提问来源于stack exchange,提问作者Nono-Man
相关产品推荐
相关产品推荐

