
本文详解 laravel sanctum 在混合渲染(blade + vue)场景下如何正确实现 csrf 保护与用户身份同步,涵盖 csrf cookie 预加载、axios 配置、会话认证逻辑及常见误区。
本文详解 laravel sanctum 在混合渲染(blade + vue)场景下如何正确实现 csrf 保护与用户身份同步,涵盖 csrf cookie 预加载、axios 配置、会话认证逻辑及常见误区。
在 Laravel + Vue 混合开发(即 Vue 组件嵌入 Blade 模板、共享同一会话)中,许多开发者误以为“只要设置了 并调用 /sanctum/csrf-cookie 就能自动完成用户认证”——但事实并非如此。CSRF Token 仅用于防止跨站请求伪造,它本身不携带用户身份;真正的身份认证依赖于 PHP Session(Web Guard)或 API Token(API Guard),而 Sanctum 的核心作用,是为这两种场景提供统一、轻量的认证桥梁。
✅ 正确认知:CSRF ≠ Authentication
- GET /sanctum/csrf-cookie 仅向客户端写入一个 XSRF-TOKEN cookie(HttpOnly),并初始化 session(若尚未存在)。
- 它不会登录用户,也不会触发 Auth::check() 为 true —— 用户是否已登录,取决于你是否已通过 LoginController 等方式调用 Auth::login($user) 并持久化 session。
- 你的 Blade 中 @if(auth()->check()) 判断的是 服务端 Session 状态,而非前端 JS 变量或 Axios 请求头。
✅ 前端关键配置(Vue + Axios)
确保 Axios 在每次请求中携带凭证(cookies)并读取 CSRF token:
// resources/js/bootstrap.js 或 main.js
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
window.axios.defaults.withCredentials = true; // ⚠️ 必须启用,否则 session 不传递
// 自动从 meta 标签注入 X-CSRF-TOKEN(适用于非 JSON 请求如表单提交)
const csrfToken = document.head.querySelector('meta[name="csrf-token"]');
if (csrfToken) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = csrfToken.content;
}
// 对于 API 请求(如 login),推荐使用此方式预加载 CSRF cookie
export const initializeCsrf = () => {
return axios.get('/sanctum/csrf-cookie')
.then(() => console.log('CSRF cookie set'));
};
? 提示:withCredentials: true 是混合渲染场景的强制要求,它使浏览器在跨域(若存在)或同域请求中均发送 cookies,从而维持 Laravel 的 session 关联。
✅ 后端 Login Controller 修正(Session 认证)
你当前的 login() 方法创建了 Sanctum Token,但未登录用户到 Web Guard,导致 Blade 中 auth()->check() 仍为 false。若需 Blade 与 Vue 共享登录态,请改用 session 认证(而非纯 API Token):
// app/Http/Controllers/Auth/LoginController.php
public function login(AuthRequest $request): JsonResponse
{
$credentials = $request->only('email', 'password');
if (!Auth::attempt($credentials)) {
return response()->json(['message' => 'Invalid credentials'], 401);
}
// ✅ 用户已登录到 web guard → Blade 中 auth()->check() 将返回 true
$user = Auth::user();
// (可选)为 Vue API 调用额外发放 Sanctum Token(如需调用 /api/* 路由)
$token = $user->createToken('web-session')->plainTextToken;
ProcessUserDevice::dispatch($user->id, $_SERVER, $token);
return response()->json([
'isLoggedin' => true,
'user' => $user,
'token' => $token // 供 Vue 中 axios 设置 Authorization: Bearer xxx
]);
}
同时,在 config/auth.php 确保 web guard 使用 session driver,并且 sanctum guard 存在(Sanctum 会自动注册):
'defaults' => [
'guard' => 'web', // ← 确保默认 guard 是 web
'passwords' => 'users',
],
✅ Blade 中安全输出用户数据(防 XSS)
避免直接 @php ... @endphp 构造全局变量。更健壮的方式是通过 @json 输出,并在 Vue 初始化时消费:
<!-- resources/views/layouts/app.blade.php -->
<script>
window.Laravel = @json([
'csrfToken' => csrf_token(),
'user' => auth()->check() ? [
'id' => auth()->id(),
'name' => auth()->user()->name,
'email' => auth()->user()->email,
] : null,
'isLoggedIn' => auth()->check()
]);
</script>
Vue 组件中即可访问:
console.log(window.Laravel.user); // 安全、预渲染的用户信息
⚠️ 注意事项总结
- ❌ 不要混淆:/sanctum/csrf-cookie ≠ 登录接口;它只是 CSRF 准备步骤。
- ✅ 登录必须显式调用 Auth::attempt() 或 Auth::login() 才能激活 session。
- ✅ 前端 Axios 必须设置 withCredentials: true,否则 session cookie 不发送。
- ✅ 若使用 Sanctum::authenticate()(如 API 路由),需配合 Authorization: Bearer {token},此时 auth()->check() 默认不生效(除非指定 guard)。
- ✅ 生产环境务必配置 SESSION_DOMAIN 和 SANCTUM_STATEFUL_DOMAINS(见 config/sanctum.php),尤其涉及子域名。
通过以上配置,你将实现:
✅ Blade 模板实时感知登录态(auth()->check())
✅ Vue 组件通过 window.Laravel.user 获取初始用户数据
✅ 所有 Axios 请求自动携带 session 与 CSRF 保护
✅ 登录后 API 调用(如获取用户资料)持续有效
这才是 Laravel Sanctum 在传统 SSR+Vue 混合架构中的最佳实践路径。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











