Guard(ガード)
「どうやってユーザーを識別するか」の方式です。Web画面はセッションで覚える session ガード、APIはリクエストごとにトークンを見る token ガードが基本。どのガードを使うかは config/auth.php で設定します。
- config/auth.php (guards)
- SessionGuard
- TokenGuard
- Auth::guard('web')
Laravel 認証・認可フロー図解
Laravelのセキュリティは大きく2つに分かれます。認証(Authentication)は「あなたは誰か(ログイン済みか)」の確認、認可(Authorization)は「その人に、この操作をする権限があるか」の確認です。 ここではまず認証の流れをフロー図で追い、続いて認可(Gate と Policy)の 使い分けをコード例つきで整理します。
ログインフォームの送信から、Guard と User Provider による本人確認、 セッション確立、その後の auth ミドルウェアによる保護、ログアウトまでの流れです。
※ Guard が「どう識別するか」、User Provider が「どこから取り出して照合するか」を担当します。 Web画面は session ガード、APIは token ガード(Sanctumなど)が基本です。
「どうやってユーザーを識別するか」の方式です。Web画面はセッションで覚える session ガード、APIはリクエストごとにトークンを見る token ガードが基本。どのガードを使うかは config/auth.php で設定します。
「ユーザーをどこから、どう取り出すか」の担当です。送られた credentials を使ってDBから該当ユーザーを探し、パスワードのハッシュ照合まで行います。標準は Eloquent プロバイダ(App\Models\User を使用)。
認証に成功したら「このブラウザはログイン済み」という印をセッションに保存します。以降のリクエストはセッションのIDをCookieで送ることで、毎回ログインし直さずに済みます。remember me は別の永続Cookieで期限を延ばす仕組みです。
保護したいルートに付ける「関所」です。リクエストがログイン済みかをガードに問い合わせ、未ログインならログイン画面へリダイレクト(APIなら401)します。ルートやコントローラに ->middleware('auth') で付けます。
認証で「ログイン済み」と分かった後、その人がこの操作をしてよいかを判定するのが認可です。判定ルールの置き場所としてGate と Policy の2つがあります。
| 観点 | Gate(ゲート) | Policy(ポリシー) |
|---|---|---|
| 何に対する権限か | 特定のモデルに紐づかない、単発・横断的な権限 | 特定のモデル(例: Post)に対する一連の権限をまとめる |
| 定義場所 | AuthServiceProvider の boot() で Gate::define(...) | app/Policies/ 配下のポリシークラス(1モデル1クラス) |
| 生成コマンド | (手書きでクロージャを定義) | php artisan make:policy PostPolicy --model=Post |
| 向いている場面 | 「管理者だけ」など、モデルに依存しない単純な判定 | 「自分の投稿だけ編集可」など、モデル単位の複数操作 |
| 呼び出し例 | Gate::allows('admin-only') | $user->can('update', $post) |
if ($user->can('update', $post)) { /* ... */ }@can('update', $post) <a href="...">編集</a> @endcan$this->authorize('update', $post);if (Gate::allows('update-post', $post)) { /* ... */ }// AuthServiceProvider::boot()
Gate::define('admin-only', function ($user) {
return $user->is_admin;
});
// コントローラ
if (Gate::allows('admin-only')) {
// 管理者だけの処理
}
// Blade
@can('admin-only')
<a href="/admin">管理画面</a>
@endcan// php artisan make:policy PostPolicy --model=Post
class PostPolicy
{
public function update(User $user, Post $post): bool
{
return $user->id === $post->user_id;
}
}
// コントローラ: 権限なしなら 403
public function update(Post $post)
{
$this->authorize('update', $post);
// 自分の投稿だけ更新できる
}認証まわりには公式パッケージが複数あり、名前が似ていて混乱しがちです。 「どれが何用か」を短くまとめます。
最小構成のログイン画面つきスターター
ログイン・登録・パスワードリセットなどの画面と処理を一式生成。シンプルで読みやすく、認証の仕組みを学ぶ入口に最適。中身は普通のBladeやControllerなので改造しやすい。
画面を持たない認証バックエンド(ロジックのみ)
ログインや2段階認証などの「処理側」だけを提供し、画面は自分で用意する前提。SPAや独自デザインで認証ロジックだけ借りたいときに使う。Breeze/Jetstream の裏側でも動いている。
SPA・モバイル・シンプルなAPIトークン認証
同一ドメインのSPAはCookieセッションで、外部アプリには軽量なAPIトークンで認証。多くのAPIにはこれで十分。OAuthのような重い仕組みは不要なときの第一候補。
本格的なOAuth2サーバー
第三者アプリに権限を委譲するOAuth2をフル実装。アクセストークン発行やスコープ管理が必要な大規模・外部連携向け。要件が重いぶん、まずは Sanctum で足りないか検討する。
リクエスト全体の流れはリクエストライフサイクル、部品の位置関係は全体マップも参考になります。