> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Laravel Passport（OAuth2 伺服器實作）

> 說明如何以 Laravel Passport 實作 OAuth2 伺服器。涵蓋與 Sanctum 的分工、安裝、用戶端管理、Scope 與 token 運用。

## 什麼是 Passport

Laravel Passport 是讓 Laravel 應用程式作為 OAuth2 授權伺服器運作的官方套件。
用於第三方應用整合，或需要嚴謹 OAuth2 流程的 API。

```mermaid theme={null}
sequenceDiagram
    participant User as 使用者
    participant Client as OAuth 用戶端
    participant App as Laravel 應用<br>(Passport)
    participant API as 受保護的 API

    User->>Client: 開始連結
    Client->>App: 授權請求
    App->>User: 顯示同意畫面
    User->>App: 許可
    App-->>Client: 授權碼
    Client->>App: 以授權碼換取存取權杖
    App-->>Client: 存取權杖
    Client->>API: 附帶 Bearer 權杖呼叫 API
    API-->>Client: 回應
```

## Passport 與 Sanctum 比較

若必須使用 OAuth2 就選 Passport。
若目的是單純的 API token 認證或 SPA／行動裝置認證，就選 Sanctum。

| 面向   | Passport                                            | Sanctum              |
| ---- | --------------------------------------------------- | -------------------- |
| 目的   | OAuth2 伺服器實作                                        | 單純的 API 認證           |
| 適用情境 | 外部應用整合、遵循 OAuth2 標準、[MCP 伺服器](/zh-TW/mcp#oauth-2-1) | 自家 SPA、行動裝置、個人 token |
| 複雜度  | 高                                                   | 低                    |

<Info>
  在建置由 AI 用戶端存取的 [MCP 伺服器](/zh-TW/mcp)時，官方推薦使用 Passport。因為 MCP 用戶端通常以 OAuth 認證為前提。
</Info>

## 安裝

Laravel 13 官方推薦使用 `install:api --passport`。

```shell theme={null}
php artisan install:api --passport
```

若在既有專案中手動導入，可用以下指令進行設定。

```shell theme={null}
composer require laravel/passport
php artisan passport:install
```

有時初次部署只想執行金鑰產生：

```shell theme={null}
php artisan passport:keys
```

## 設定

### User model

在 `User` model 加入 `HasApiTokens` trait 與 `OAuthenticatable` 介面。

```php theme={null}
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 guard

在 `config/auth.php` 的 `api` guard 中使用 `passport` driver。

```php theme={null}
'guards' => [
    'api' => [
        'driver' => 'passport',
        'provider' => 'users',
    ],
],
```

### 服務提供者設定

可在 `AppServiceProvider` 的 `boot()` 定義 scope 與 token 有效期限。

```php theme={null}
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 grant）用的用戶端

```shell theme={null}
php artisan passport:client
```

此用戶端會用於伴隨使用者同意畫面的 OAuth2 標準流程。

### 用戶端憑證授權（client credentials grant）用的用戶端

```shell theme={null}
php artisan passport:client --client
```

在機器對機器通訊的端點中，使用 `EnsureClientIsResourceOwner` middleware。

```php theme={null}
use Laravel\Passport\Http\Middleware\EnsureClientIsResourceOwner;

Route::get('/orders', function () {
    // ...
})->middleware(EnsureClientIsResourceOwner::using('orders:read'));
```

## Token 管理

### 授予 Scope

```php theme={null}
$accessToken = $user->createToken(
    'dashboard-token',
    ['orders:read', 'orders:create']
)->accessToken;
```

### 檢查 Scope

```php theme={null}
use Laravel\Passport\Http\Middleware\CheckToken;

Route::get('/orders', function () {
    // ...
})->middleware(['auth:api', CheckToken::using('orders:read')]);
```

### 失效

```php theme={null}
use Laravel\Passport\Passport;

$token = Passport::token()->find($tokenId);
$token?->revoke();
```

## 保護 API 路由

需以使用者存取權杖保護的 API 加上 `auth:api`。

```php theme={null}
Route::middleware('auth:api')->group(function () {
    Route::get('/user', fn (Request $request) => $request->user());
    Route::get('/orders', [OrderController::class, 'index']);
});
```

<Warning>
  用戶端憑證授權的路由請使用 `EnsureClientIsResourceOwner`，而非 `auth:api`。
</Warning>

## Personal Access Token

適用於不使用完整 OAuth2 流程，而由使用者本人核發 API token 的情境。

```shell theme={null}
php artisan passport:client --personal
```

```php theme={null}
$token = $request->user()->createToken('cli-token', ['orders:read'])->accessToken;
```

<Info>
  若 Personal Access Token 是主要用途，Laravel 官方也建議考慮使用 Sanctum。
</Info>

## 相關連結

* [Laravel 官方文件：Passport](https://laravel.com/docs/13.x/passport)
* [Laravel 官方文件：Sanctum](https://laravel.com/docs/13.x/sanctum)


## Related topics

- [Socialite for Discord](/zh-TW/packages/socialite-discord.md)
- [用 Laravel 構建 MCP 伺服器](/zh-TW/advanced/mcp-server.md)
- [Laravel Sanctum（API token 認證）](/zh-TW/sanctum.md)
- [Laravel AI Agent 支援 MCP 伺服器](/zh-TW/blog/ai-sdk-mcp-client.md)
- [Socialite(LINE Login)- LINE SDK for Laravel](/zh-TW/packages/laravel-line-sdk/socialite.md)
