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') } } })
问题原因
核心问题有两个:
- Vue端未保存并携带API Token:Laravel登录接口返回了
token,但Vuex的loginaction没有接收返回值,也没将Token设置到Axios请求头中。Sanctum的API Token认证要求请求头携带Authorization: Bearer {token}才能通过验证。 - 需确认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
相关产品推荐
相关产品推荐

