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

Laravel 11 Sanctum对接Vue3获取用户信息时出现401未授权错误

问题描述

我是Vue 3和Laravel Sanctum的新手,用Laravel 11 Sanctum搭建API服务,Vue 3作为客户端调用API。登录功能正常,但调用/api/user获取用户信息时出现401未授权错误。

相关代码

Laravel登录函数

public function __invoke(Request $request)
{
    $data = $request->validate([
       'email' => ['required', 'email'],
       'password' => ['required'],
    ]);

    $user = User::where('email', $data['email'])->first();

    if (!$user || !Hash::check($data['password'], $user->password)) {
        return response('Unauthorized.', 401);
    }

    $token = $user->createToken('auth_token')->plainTextToken;

    return response([
        'user' => $user,
        'token' => $token,
    ]);
}

Vue登录组件代码

export default {
  setup() {
    const store = useStore()
    const login = () => {
      store.dispatch('login', {
        email: 'cassie81@example.com',
        password: 'password'
      })
    }
    return {login}
  }
}

Vuex Store文件

import {createStore} from "vuex";
import axios from "axios";

export default createStore({
    state() {
        return {
            authenticated: false,
            user: null
        }
    },
    getters: {
        authenticated(state) {
            return state.authenticated
        },
        user(state) {
            return state.user
        }
    },
    mutations: {
        SET_AUTHENTICATED(state, authenticated) {
            state.authenticated = authenticated
        },
        SET_USER(state, user) {
            state.user = user
        }
    },
    actions: {
        authenticate({commit}) {
            axios.get('/api/user').then((response) => {
                commit('SET_AUTHENTICATED', true)
                commit('SET_USER', response.data)
            }).catch(() => {
                commit('SET_AUTHENTICATED', false)
                commit('SET_USER', null)
            })
        },
        async login({dispatch}, credentials) {
            await axios.get('/sanctum/csrf-cookie')
            await axios.post('/login', credentials)
            dispatch('authenticate')
        }
    }
})

问题原因

核心问题有两个:

  1. Vue端未保存并携带API Token:Laravel登录接口返回了token,但Vuex的login action没有接收返回值,也没将Token设置到Axios请求头中。Sanctum的API Token认证要求请求头携带Authorization: Bearer {token}才能通过验证。
  2. 需确认Laravel端路由保护:/api/user路由必须使用auth:sanctum中间件,否则无法触发Token认证逻辑。

解决方案

1. 修改Vuex的login action,保存并设置Token

更新login方法,接收登录接口返回的Token,保存到本地存储并配置Axios请求头:

async login({dispatch}, credentials) {
    await axios.get('/sanctum/csrf-cookie')
    // 接收登录接口返回数据
    const response = await axios.post('/login', credentials)
    // 保存Token到本地存储
    localStorage.setItem('auth_token', response.data.token)
    // 设置Axios默认请求头
    axios.defaults.headers.common['Authorization'] = `Bearer ${response.data.token}`
    dispatch('authenticate')
}

2. 页面初始化时自动加载Token

在Vue项目入口文件(如main.js)中添加代码,页面加载时读取本地Token并配置Axios,避免刷新后丢失认证状态:

import axios from 'axios'

// 配置Axios基础URL(根据后端地址调整)
axios.defaults.baseURL = 'http://localhost:8000'

// 读取本地存储的Token并设置请求头
const token = localStorage.getItem('auth_token')
if (token) {
    axios.defaults.headers.common['Authorization'] = `Bearer ${token}`
}

3. 确认Laravel路由配置

确保/api/user路由被auth:sanctum中间件保护,在routes/api.php中:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

4. 检查Laravel跨域配置

在.env文件中配置正确的跨域参数(根据前端地址调整):

SESSION_DOMAIN=.localhost
SANCTUM_STATEFUL_DOMAINS=localhost:5173

同时确认config/cors.php中的supports_credentials设置为true:

'supports_credentials' => true,

内容的提问来源于stack exchange,提问作者Mohsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 08:07:35