Laravel 9.52+Vue项目:如何用Http-only Cookie替代LocalStorage存储JWT?
针对你的场景,Laravel Sanctum原生支持Http-only Cookie的SPA认证方案,完全可以替代LocalStorage存储令牌的方式,以下是适配Laravel 9.x的具体实现步骤:
1. 基础配置调整
1.1 环境变量配置
修改.env文件,设置适配跨域的会话域名:
SESSION_DOMAIN=.localhost # 适配前端localhost:3000和后端localhost:8000的跨域场景 SANCTUM_STATEFUL_DOMAINS=localhost:3000,127.0.0.1:3000
1.2 Sanctum配置
修改config/sanctum.php,确保stateful数组包含你的前端域名:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost:3000,127.0.0.1:3000')),
1.3 会话与CORS配置
- 修改
config/session.php,确认Http-only和SameSite设置:
'http_only' => true, // 默认已开启,禁止改为false 'same_site' => 'lax', // 根据需求可选strict,lax兼容大部分场景
- 修改
config/cors.php,开启跨域凭证支持:
'supports_credentials' => true, 'allowed_origins' => ['http://localhost:3000'], // 替换为你的前端实际域名
2. 后端认证逻辑调整
2.1 路由配置
在routes/api.php中定义登录/登出路由(无需生成API令牌):
use App\Http\Controllers\Auth\LoginController; use Illuminate\Support\Facades\Route; Route::post('/login', [LoginController::class, 'store']); Route::post('/logout', [LoginController::class, 'destroy'])->middleware('auth:sanctum');
2.2 登录控制器实现
替换原有的令牌生成逻辑,使用Laravel自带的Auth::attempt()完成登录,Sanctum会自动设置Http-only会话Cookie:
namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class LoginController extends Controller { public function store(Request $request) { $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); if (!Auth::attempt($request->only('email', 'password'))) { return response()->json(['message' => '无效的登录凭证'], 401); } return response()->json([ 'user' => Auth::user(), // 无需返回令牌,Cookie由后端自动设置 ]); } public function destroy(Request $request) { Auth::guard('web')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return response()->json(['message' => '登出成功']); } }
3. 前端Vue适配
3.1 Axios全局配置
确保Axios自动携带Cookie,在Vue项目的入口文件(如main.js)中添加:
import axios from 'axios'; axios.defaults.baseURL = 'http://localhost:8000/api'; axios.defaults.withCredentials = true; // 关键:允许携带跨域Cookie
3.2 登录逻辑调整
登录前先请求Sanctum的CSRF接口,再发送登录请求(无需存储令牌到LocalStorage):
// 示例Vue组件中的登录方法 async handleLogin() { try { // 先获取CSRF Cookie,Sanctum会自动设置XSRF-TOKEN await axios.get('/sanctum/csrf-cookie'); // 发送登录请求 const response = await axios.post('/login', { email: this.email, password: this.password }); // 登录成功后直接处理用户信息,无需存令牌 this.currentUser = response.data.user; } catch (error) { console.error('登录失败:', error.response.data.message); } }
关键安全说明
- Http-only Cookie无法被前端JS读取,彻底避免XSS攻击窃取令牌的风险;
- 配合Sanctum的CSRF令牌机制,可有效防御CSRF攻击;
- 无需手动管理令牌生命周期,Laravel会话系统会自动处理过期和刷新。
内容的提问来源于stack exchange,提问作者Elielson_and
相关产品推荐
相关产品推荐

