深入掌握Laravel 12中使用Sanctum实现的API认证 - Kritimyantra

作者:API传播员 · 2026-01-10 · 阅读时间:6分钟

构建现代 Laravel Sanctum 是一个轻量级且功能强大的身份验证系统,能够在简单性和安全性之间取得平衡。本文将深入探讨 Laravel Sanctum 的工作原理、核心功能,并通过实例展示如何在项目中实现它。


什么是 Laravel Sanctum?

Laravel Sanctum 是一个极简主义的身份验证包,专为解决以下两大核心挑战而设计:

  1. **API 请求
  2. SPA 身份验证:通过 Laravel 的会话 Cookie,为单页应用程序(SPA)提供无缝的身份验证,而无需使用复杂的令牌机制。

无论是构建任务管理 API、带有 Vue.js 前端的电商平台,还是移动应用程序,Sanctum 都能简化身份验证流程,让开发者专注于核心业务逻辑。


为什么选择 Sanctum?

  • 避免 OAuth 的复杂性:Sanctum 适用于简单场景,避免了 OAuth2 的繁琐设置。
  • 双重身份验证模式:支持通过令牌为第三方客户端(如移动应用程序)提供认证,同时通过 Cookie 为 SPA 提供认证。
  • 安全性优先:内置 CSRF 保护、令牌撤销和过期功能。
  • 轻量级设计:专为不需要完整 OAuth 设置的项目而设计。

接下来,我们将通过实际示例展示如何使用 Sanctum。


安装与设置

首先,创建一个新的 Laravel 12 项目并安装 Sanctum:

laravel new task-manager
cd task-manager
composer require laravel/sanctum

安装完成后,运行数据库迁移以创建 Sanctum 的令牌表:

php artisan migrate

示例 1:为任务管理器颁发 API 令牌

假设您正在开发一个任务管理器 API,用户需要生成令牌以通过移动应用程序访问其任务。以下是实现步骤:

步骤 1:在用户模型中启用 API 令牌功能

User 模型中引入 HasApiTokens

use LaravelSanctumHasApiTokens;

class User extends Authenticatable
{
    use HasApiTokens, HasFactory, Notifiable;
}

步骤 2:创建生成令牌的路由

routes/api.php 中添加以下代码:

use IlluminateHttpRequest;

Route::post('/tokens/create', function (Request $request) {
    $request->validate([
        'token_name' => 'required',
    ]);    $token = $request->user()->createToken(
        $request->token_name,
        ['task:read', 'task:create'] // 定义令牌权限
    );    return response()->json(['token' => $token->plainTextToken]);
})->middleware('auth:sanctum');

用户可以通过向 /api/tokens/create 发送 POST 请求来生成令牌。例如,移动应用程序可以请求一个名为 "MyTaskApp" 的令牌,该令牌具有读取和创建任务的权限。


示例 2:使用令牌能力保护路由

通过 Sanctum 的能力(abilities),可以限制令牌对特定路由的访问权限。

保护任务相关路由

Route::middleware(['auth:sanctum', 'ability:task:read'])->group(function () {
    Route::get('/tasks', [TaskController::class, 'index']);
});

Route::middleware(['auth:sanctum', 'ability:task:create'])->group(function () {
    Route::post('/tasks', [TaskController::class, 'store']);
});

只有具有 task:read 能力的令牌可以访问 /tasks 路由,而具有 task:create 能力的令牌才能添加新任务。如果令牌缺少相应能力,Sanctum 会自动阻止访问。


示例 3:Vue.js 前端的 SPA 身份验证

假设任务管理器的前端是一个托管在 https://tasks.example.com 的 Vue.js SPA,Sanctum 可以通过会话而非令牌对其进行身份验证。

步骤 1:配置 Sanctum

config/sanctum.php 中,允许 SPA 的域名:

'stateful' => [
    'tasks.example.com',
],

步骤 2:设置 CORS

确保 config/cors.php 配置允许凭据:

'supports_credentials' => true,

步骤 3:在 Vue.js 中实现身份验证

在 Vue 应用中,首先获取 CSRF Cookie,然后进行登录:

axios.get('https://api.example.com/sanctum/csrf-cookie').then(() => {
    // 登录
    axios.post('https://api.example.com/login', {
        email: 'user@example.com',
        password: 'password',
    }).then(response => {
        // 登录成功后获取任务
        axios.get('https://api.example.com/api/tasks').then(tasks => {
            console.log(tasks.data);
        });
    });
});

通过会话 Cookie,SPA 可以安全地与后端 API 交互,同时享受内置的 CSRF 保护。


示例 4:移动应用程序身份验证(Flutter)

对于移动应用程序,用户可以通过电子邮件和密码登录以获取令牌。

步骤 1:创建登录路由

routes/api.php 中添加以下代码:

use IlluminateSupportFacadesHash;

Route::post('/mobile/login', function (Request $request) {
    $request->validate([
        'email' => 'required|email',
        'password' => 'required',
        'device_name' => 'required',
    ]);    $user = User::where('email', $request->email)->first();    if (!$user || !Hash::check($request->password, $user->password)) {        return response()->json(['error' => 'Invalid credentials'], 401);
    }    return response()->json([
        'token' => $user->createToken($request->device_name)->plainTextToken,
    ]);
});

步骤 2:在 Flutter 中使用令牌

在 Flutter 应用中,存储令牌并将其附加到 API 请求中:

final response = await http.post(
  Uri.parse('https://api.example.com/api/tasks'),
  headers: {
    'Authorization': 'Bearer $yourToken',
    'Accept': 'application/json',
  },
  body: {
    'title': 'New Task',
  },
);

测试 Sanctum 身份验证

Sanctum 提供了简化测试的工具。例如,测试受保护的任务路由:

use AppModelsUser;
use LaravelSanctumSanctum;

public function test_user_can_fetch_tasks()
{
    Sanctum::actingAs(
        User::factory()->create(),
        ['task:read'] // 授予能力
    );    $response = $this->getJson('/api/tasks');    $response->assertOk();
}

最后提示

  • 撤销令牌:用户可以通过设置页面撤销令牌。
  • 令牌过期:在 config/sanctum.php 中配置令牌过期时间以增强安全性。
  • 避免混用认证模式:为 SPA 使用 Cookie,为第三方客户端使用令牌。

结论

Laravel Sanctum 是一个灵活且安全的 API 身份验证解决方案,无论是保护 Vue.js 应用、移动应用还是公共 API,Sanctum 都能提供简单高效的支持。通过结合令牌和会话认证,开发者可以轻松实现安全的身份验证,而无需面对复杂的设置。

在下一个 Laravel 12 项目中试试 Sanctum,提升您的身份验证体验吧!

原文链接: https://www.kritimyantra.com/blogs/mastering-api-authentication-in-laravel-12-with-sanctum-a-developers-guide