Laravel 用 Sanctum 做 SPA 鉴权:令牌签发、多 guard 与前端配合
test12026-09-261 次阅读
Sanctum 的两种模式
Sanctum 同时支持"令牌(token)"和"会话(session cookie)"两套机制。SPA 与第一方前端走的是会话模式:前端和 API 同域(或配好 CORS),登录后由后端下发 CSRF cookie,之后请求带 X-XSRF-TOKEN 即可,不需要在请求头里塞 Bearer token。
后端配置
先在 config/cors.php 放开凭据,并允许前端源;config/sanctum.php 的 guard 用 web 即可复用会话驱动。
// config/cors.php 关键项
'paths' => ['api/*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:5173'],
'supports_credentials' => true,
// routes/api.php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
Route::get('/sanctum/csrf-cookie', function () {
return response()->noContent();
});
Route::post('/login', [AuthController::class, 'login']);
Route::middleware('auth:sanctum')->get('/user', fn (Request $r) => $r->user());
登录签发会话
public function login(Request $request)
{
$credentials = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if (! auth()->attempt($credentials)) {
return response()->json(['message' => '账号或密码错误'], 422);
}
$request->session()->regenerate(); // 防会话固定
return response()->noContent();
}
前端配合
axios 需开启 withCredentials,并在调用任何受保护接口前先请求一次 CSRF cookie。
// 进入应用时先拿 cookie
await axios.get('/sanctum/csrf-cookie', { withCredentials: true });
// 之后所有请求带凭据
axios.defaults.withCredentials = true;
await axios.post('/api/login', { email, password });
const { data: user } = await axios.get('/api/user');
多 guard 与令牌能力
若系统里还有移动端或第三方需要长期令牌,可保留 auth:sanctum 的 token 能力:$user->createToken('mobile') 生成 Bearer token,前端 SPA 仍走 cookie 会话,两者共用同一套中间件互不冲突。注意 CSRF cookie 接口必须放在 web 中间件组(默认 sanctum/csrf-cookie 已在其中),否则 cookie 不会下发。
- 同域 SPA 优先用会话模式,天然防 CSRF,无需前端管理 token 过期。
- 跨域时务必
supports_credentials=true且前端withCredentials,否则 cookie 不生效。 - 退出登录调用
auth()->guard('web')->logout()并销毁会话。
T
test1
文章作者
Sanctum 的两种模式 Sanctum 同时支持"令牌(token)"和"会话(session cookie)"两...
- 分类
- 技术
- 发布时间
- 2026-09-26
- 字数
- 约 1824 字
- 阅读
- 1 次
