什么是 Passport
Laravel Passport 是让 Laravel 应用作为 OAuth2 授权服务器运行的官方包。
用于第三方应用集成,或需要严格遵循 OAuth2 流程的 API。
Passport 与 Sanctum 的对比
如果必须支持 OAuth2,请选择 Passport。
如果只是单纯的 API 令牌认证,或用于 SPA / 移动端认证,请选择 Sanctum。
| 维度 | Passport | Sanctum |
|---|
| 目标 | 实现 OAuth2 服务器 | 简单的 API 认证 |
| 适用场景 | 第三方应用集成、遵循 OAuth2 标准 | 自家 SPA、移动端、个人用令牌 |
| 复杂度 | 高 | 低 |
Laravel 13 官方推荐使用 install:api --passport。
php artisan install:api --passport
如果要在已有项目中手动引入,也可以通过下面的命令进行配置。
composer require laravel/passport
php artisan passport:install
首次部署时,可能只想生成密钥。
php artisan passport:keys
User 模型
在 User 模型上添加 HasApiTokens trait 和 OAuthenticatable 接口。
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\Contracts\OAuthenticatable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable implements OAuthenticatable
{
use HasApiTokens, HasFactory, Notifiable;
}
auth 守卫
在 config/auth.php 中,让 api 守卫使用 passport 驱动。
'guards' => [
'api' => [
'driver' => 'passport',
'provider' => 'users',
],
],
服务提供者配置
在 AppServiceProvider 的 boot() 中可以定义作用域并设置令牌有效期。
use Carbon\CarbonInterval;
use Laravel\Passport\Passport;
public function boot(): void
{
Passport::tokensCan([
'orders:read' => '查看订单',
'orders:create' => '创建订单',
]);
Passport::defaultScopes(['orders:read']);
Passport::tokensExpireIn(CarbonInterval::days(15));
Passport::refreshTokensExpireIn(CarbonInterval::days(30));
Passport::personalAccessTokensExpireIn(CarbonInterval::months(6));
}
客户端管理
授权码授权(Authorization Code)客户端
php artisan passport:client
这种客户端用于伴有用户同意页面的 OAuth2 标准流程。
客户端凭证授权(Client Credentials)客户端
php artisan passport:client --client
对于机器间通信的接口,请使用 EnsureClientIsResourceOwner 中间件。
use Laravel\Passport\Http\Middleware\EnsureClientIsResourceOwner;
Route::get('/orders', function () {
// ...
})->middleware(EnsureClientIsResourceOwner::using('orders:read'));
令牌管理
附加作用域
$accessToken = $user->createToken(
'dashboard-token',
['orders:read', 'orders:create']
)->accessToken;
校验作用域
use Laravel\Passport\Http\Middleware\CheckToken;
Route::get('/orders', function () {
// ...
})->middleware(['auth:api', CheckToken::using('orders:read')]);
use Laravel\Passport\Passport;
$token = Passport::token()->find($tokenId);
$token?->revoke();
保护 API 路由
为使用用户访问令牌进行保护的 API 添加 auth:api。
Route::middleware('auth:api')->group(function () {
Route::get('/user', fn (Request $request) => $request->user());
Route::get('/orders', [OrderController::class, 'index']);
});
对于使用客户端凭证授权的路由,请使用 EnsureClientIsResourceOwner 而不是 auth:api。
Personal Access Token
适合不使用完整 OAuth2 流程,让用户自己签发 API 令牌的场景。
php artisan passport:client --personal
$token = $request->user()->createToken('cli-token', ['orders:read'])->accessToken;
如果 Personal Access Token 是主要用途,Laravel 官方也建议考虑使用 Sanctum。
相关链接