> ## 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 認證功能的基礎知識。從使用啟動套件導入認證系統，到取得已認證使用者的方法皆有說明。

## 什麼是認證

認證（Authentication）是確認發起存取的使用者「是誰」的機制。
在 Web 應用程式中，會透過登入表單接收電子郵件與密碼，若正確則將使用者資訊儲存到 Session。
後續請求會參照該 Session 來識別使用者。

Laravel 的認證功能由「Guard」與「Provider」兩個概念組成。

* **Guard**：定義每個請求如何驗證使用者。預設是 `session` guard，使用 Session 與 Cookie 來管理狀態。
* **Provider**：定義如何從資料庫取得使用者。預設使用 Eloquent。

<Info>
  認證的設定檔為 `config/auth.php`。預設設定即可對應大多數 Web 應用程式。
</Info>

```mermaid theme={null}
flowchart TD
    A["登入請求"] --> B["Guard<br>(定義認證方式)"]
    B --> C["Provider<br>(從 DB 取得使用者)"]
    C --> D{"認證檢查"}
    D -- "成功" --> E["將使用者資訊<br>儲存到 Session"]
    E --> F["導向已認證頁面"]
    D -- "失敗" --> G["導向登入畫面"]
```

## 透過啟動套件加入認證

在 Laravel 中，只要在使用 `laravel new` 建立應用程式時選擇啟動套件，就能自動建構登入、註冊、密碼重設等認證功能。這是最推薦的方式。

<Steps>
  <Step title="建立應用程式">
    使用 Laravel 安裝器建立應用程式。過程中會出現選擇啟動套件的提示。

    ```shell theme={null}
    laravel new my-app
    ```

    啟動套件可從 **React**、**Vue**、**Livewire**、**Svelte** 中選擇。
    請依團隊的技術堆疊挑選。
  </Step>

  <Step title="安裝前端相依套件">
    ```shell theme={null}
    cd my-app
    npm install && npm run build
    ```
  </Step>

  <Step title="準備資料庫">
    確認 `.env` 檔案的資料庫設定後，執行 migration。

    ```shell theme={null}
    php artisan migrate
    ```

    會套用包含 `users` 表的初始 migration。
  </Step>

  <Step title="啟動開發伺服器">
    ```shell theme={null}
    composer run dev
    ```

    在瀏覽器開啟 `http://localhost:8000`，導覽列會顯示「Register」與「Log in」連結。
    可以造訪 `/register` 註冊使用者試試看。
  </Step>
</Steps>

使用啟動套件後，以下功能可立即使用：

| 功能     | URL                 |
| ------ | ------------------- |
| 使用者註冊  | `/register`         |
| 登入     | `/login`            |
| 密碼重設   | `/forgot-password`  |
| 電子郵件驗證 | `/email/verify`     |
| 個人資料編輯 | `/settings/profile` |

<Tip>
  啟動套件產生的程式碼（Controller、Route、View）全部都存在於你自己的應用程式內，可以自由修改與客製化。
</Tip>

### 可用的啟動套件

#### React

可建構使用 React 19、TypeScript、Tailwind、[shadcn/ui](https://ui.shadcn.com) 的現代 SPA。
透過 [Inertia](https://inertiajs.com)，能在保有伺服器端路由的同時使用 React 前端。

#### Vue

採用 Vue Composition API、TypeScript、Tailwind、[shadcn-vue](https://www.shadcn-vue.com/)。
與 React 同樣使用 Inertia 與伺服器端連動。

#### Livewire

使用僅靠 PHP 即可建構動態 UI 的 [Livewire](https://livewire.laravel.com)。
最適合以 Blade 模板為主的團隊，或希望不使用 JavaScript 框架的場合。
內含 [Flux UI](https://fluxui.dev) 元件庫。

#### Svelte

使用 Svelte 5、TypeScript、Tailwind、[shadcn-svelte](https://www.shadcn-svelte.com/)。
可與 Inertia 搭配建構現代 SPA。

## 認證 Facade

使用 `Auth` Facade 可取得目前已認證的使用者資訊，或確認認證狀態。

### 取得已認證的使用者

```php theme={null}
use Illuminate\Support\Facades\Auth;

// 取得目前的使用者
$user = Auth::user();

// 只取得使用者 ID
$id = Auth::id();
```

在 Controller 中也可以從 `Request` 物件取得使用者。

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DashboardController extends Controller
{
    public function index(Request $request)
    {
        $user = $request->user();

        return view('dashboard', ['user' => $user]);
    }
}
```

### 確認認證狀態

`Auth::check()` 會以 `true` / `false` 回傳使用者是否已登入。

```php theme={null}
use Illuminate\Support\Facades\Auth;

if (Auth::check()) {
    // 已登入
} else {
    // 未登入
}
```

在 Blade 模板中使用 `@auth` 與 `@guest` 指令會很方便。

```blade theme={null}
@auth
    <p>您好，{{ Auth::user()->name }}</p>
    <a href="/logout">登出</a>
@endauth

@guest
    <a href="/login">登入</a>
    <a href="/register">註冊</a>
@endguest
```

## 保護路由

要建立只有已登入使用者能存取的路由，可以使用 `auth` middleware。

```php theme={null}
// routes/web.php

// 只有已認證使用者可存取
Route::get('/dashboard', function () {
    return view('dashboard');
})->middleware('auth');
```

未認證的使用者嘗試存取時，會自動被導向 `/login`。

若要一次保護多條路由，可使用群組。

```php theme={null}
Route::middleware('auth')->group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index']);
    Route::get('/profile', [ProfileController::class, 'show']);
    Route::get('/settings', [SettingsController::class, 'index']);
});
```

<Warning>
  若忘記加上 `auth` middleware，未登入的使用者就會能夠存取。需要保護的路由請務必套用。
</Warning>

### 訪客專用路由

要將已登入的使用者重新導向，可使用 `guest` middleware。
將其套用在登入或註冊頁面，即可把已登入的使用者轉送至儀表板。

```php theme={null}
Route::middleware('guest')->group(function () {
    Route::get('/login', [AuthController::class, 'showLogin']);
    Route::get('/register', [AuthController::class, 'showRegister']);
});
```

## 手動認證

若不使用啟動套件而想手動實作登入處理，可使用 `Auth::attempt()`。

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function login(Request $request): RedirectResponse
    {
        $credentials = $request->validate([
            'email' => ['required', 'email'],
            'password' => ['required'],
        ]);

        if (Auth::attempt($credentials)) {
            // 認證成功 — 重新產生 Session 以防止 CSRF 攻擊
            $request->session()->regenerate();

            return redirect()->intended('/dashboard');
        }

        // 認證失敗
        return back()->withErrors([
            'email' => '電子郵件或密碼不正確。',
        ])->onlyInput('email');
    }
}
```

在 `Auth::attempt()` 的第 1 個參數傳入認證資訊陣列。
密碼會自動與雜湊值比對，因此請直接傳入明文。

若要實作「保持登入狀態」功能，於第 2 個參數傳入 `true`。

```php theme={null}
// 使用「保持登入狀態」核取方塊的值
Auth::attempt($credentials, $request->boolean('remember'));
```

<Info>
  即使自行實作手動認證，也建議參考啟動套件的程式碼。可將其當作安全實作的範本。
</Info>

## 登出

要讓使用者登出，呼叫 `Auth::logout()`。
最佳做法是同時使 Session 失效並重新產生 CSRF Token。

```php theme={null}
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;

class LogoutController extends Controller
{
    public function logout(Request $request): RedirectResponse
    {
        Auth::logout();

        // 使 Session 失效
        $request->session()->invalidate();

        // 重新產生 CSRF Token
        $request->session()->regenerateToken();

        return redirect('/');
    }
}
```

路由請使用 POST 方法。

```php theme={null}
Route::post('/logout', [LogoutController::class, 'logout'])->middleware('auth');
```

在 Blade 模板中使用表單送出 POST 請求。

```blade theme={null}
<form method="POST" action="/logout">
    @csrf
    <button type="submit">登出</button>
</form>
```

## 總結

| 想要做的事    | 方法                                  |
| -------- | ----------------------------------- |
| 快速加入認證功能 | 啟動套件（`laravel new`）                 |
| 取得目前的使用者 | `Auth::user()` / `$request->user()` |
| 確認登入狀態   | `Auth::check()`                     |
| 保護路由     | `->middleware('auth')`              |
| 手動登入     | `Auth::attempt($credentials)`       |
| 登出       | `Auth::logout()`                    |

## 下一步

<Card title="Middleware" icon="shield-halved" href="/zh-TW/middleware">
  詳細了解 `auth` middleware 的機制與自訂 middleware 的建立方式。
</Card>


## Related topics

- [起始套件（Starter Kit）](/zh-TW/starter-kits.md)
- [雜湊（Hashing）](/zh-TW/hashing.md)
- [密碼重設](/zh-TW/passwords.md)
- [測試入門](/zh-TW/testing.md)
- [Svelte 入門 — 搭配 Inertia × Laravel 使用的基礎知識](/zh-TW/blog/svelte-introduction.md)
