You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 19:10:14