Laravel 11では、Webアプリケーションにおける「認可」を簡単かつ柔軟に実装するための仕組みとして、GatePolicyが提供されています。

認可は、ユーザーが特定のアクションを実行する権限があるかどうかを制御する重要な機能です。

本記事では、Laravel 11の最新情報をもとに、GateとPolicyを活用した認可機能の実装方法を詳しく解説します。

これを読めば、シンプルな認可からモデルに基づく複雑な認可まで対応できるようになります。

利用用途

  • ユーザー権限管理:特定のユーザーだけが操作可能な機能を制御。
  • セキュリティ向上:不正アクセスや操作を防止。
  • 開発効率化:認可ロジックを整理してコードの可読性を向上。

技術スタック

  • PHP: バージョン8.2以上
  • Laravel: バージョン11.x
  • データベース: MySQLまたはPostgreSQL(任意)
  • 環境: Composer、PHP開発サーバーまたはLaravel Sail

GateとPolicyの違い

機能GatePolicy
定義場所クロージャとしてAuthServiceProviderに記述専用クラスとして作成
適用範囲シンプルな認可ロジック特定モデルやリソースに関連付けた認可ロジック
主な用途単純な条件判定モデル単位での詳細な権限管理

1. Gateの実装方法

Gateは、特定のモデルに依存しないシンプルな認可ロジックを定義する際に使用します。

Gateの定義

App\Providers\AuthServiceProvider内で定義します。

use Illuminate\Support\Facades\Gate;

public function boot(): void
{
    // ①管理者のみ許可
    Gate::define('view-admin-dashboard', function ($user) {
        return $user->is_admin;
    });

    // ②自分の投稿のみ編集可能
    Gate::define('update-post', function ($user, $post) {
        return $user->id === $post->user_id;
    });
}

Gateによる認可チェック

以下のようにコントローラーやビュー内で使用できます。

use Illuminate\Support\Facades\Gate;

public function update(Request $request, Post $post)
{
    // 認可チェック(403エラーをスロー)
    Gate::authorize('update-post', $post);

    // 更新処理
    $post->title = $request->input('title');
    $post->save();

    return redirect()->route('posts.index')->with('success', '投稿が更新されました。');
}

if文で記述する方法

if (Gate::allows('update-post', $post)) {
    // 更新処理
}

Bladeテンプレートでの使用例

@can('update-post', $post)
    <a href="{{ route('posts.edit', $post) }}">編集</a>
@endcan

ルート(web.phpなど)にGateを適用する例

use App\Http\Controllers\PostController;

// ①管理者専用ページ
Route::get('/admin', [AdminController::class, 'index'])
    ->middleware('can:admin')
    ->name('admin.index');

// ②自分の投稿のみ編集可能なページ
Route::get('/posts/{post}/edit', [PostController::class, 'edit'])
    ->middleware('can:update-post,post')
    ->name('posts.edit');

ポイント

  • can:ability-name[,model]形式でミドルウェアを指定します。
  • モデルが必要な場合はカンマ区切りで渡します(例: can:update-post,post)。
  • ルートモデル結合の設定を適切に行います(※コントローラー側のアクション引数のモデルの変数名も合わせること)。

2. Policyの実装方法

Policyは、特定のモデルに関連する認可ロジックをまとめるために使用します。

Policyクラスの作成

以下のコマンドでPolicyクラスを生成します。

php artisan make:policy PostPolicy --model=Post

Policyクラスの編集

生成されたPostPolicyクラスで認可ロジックを定義します。

namespace App\Policies;

use App\Models\Post;
use App\Models\User;

class PostPolicy
{
    public function update(User $user, Post $post)
    {
        return $user->id === $post->user_id;
    }

    public function delete(User $user, Post $post)
    {
        return $user->id === $post->user_id || $user->is_admin;
    }
}

Policyとモデルの紐付け

モデルとポリシーが命名規則に従っている場合、自動的に関連付けられます。

命名規則のポイント

  • モデル名: Post
  • ポリシー名: PostPolicy
  • 配置場所: app/Policies/PostPolicy.php

検索順序

  1. まず app/Models/Policies ディレクトリを検索
  2. 次に app/Policies ディレクトリを検索
  3. モデル名に Policy サフィックスを付けたクラスを探す

このように配置することで、Laravel は自動的にモデルとポリシーを関連付けます。手動で AuthServiceProvider に登録する必要はありません。

手動で紐づける場合、AuthServiceProviderでPolicyとモデルを登録します。

use App\Models\Order;
use App\Policies\PostPolicy;
use Illuminate\Support\Facades\Gate;

/**
 * アプリケーションの全サービスの初期起動処理
 */
public function boot(): void
{
    Gate::policy(Post::class, PostPolicy::class);
}

Policyの呼び出し

コントローラー内で以下のように使用します。

public function destroy(Post $post)
{
    // 認可チェック(403エラーをスロー)
    $this->authorize('delete', $post);

    // 削除処理
    $post->delete();

    return redirect()->route('posts.index')->with('success', '投稿が削除されました。');
}

Bladeテンプレートでの使用例

@can('delete', $post)
    <button>削除</button>
@endcan

3. Inline Authorization(インライン認可)

簡易的な認可チェックにはインライン方式も利用できます。

use Illuminate\Support\Facades\Gate;

// 管理者のみ許可(許可の場合)
Gate::allowIf(fn ($user) => $user->is_admin);

// 管理者以外は拒否(拒否の場合)
Gate::denyIf(fn ($user) => !$user->is_admin);

まとめ

Laravel 11では、GateとPolicyを使い分けることで柔軟な認可ロジックを構築できます。

小規模なアプリケーションではGate、大規模なアプリケーションやモデルベースの認可ではPolicyが適しています。

これらを適切に活用し、セキュアで効率的なアプリケーション開発を進めましょう!

この記事をシェアする

2025年エンジニアの必読書

エンジニアなら読んでおきたい必読書を紹介します。

AI関連
コード×AI―ソフトウェア開発者のための生成AI実践入門

コード×AI―ソフトウェア開発者のための生成AI実践入門

もうプログラムを書く時代は終わりました。これを読めば「AIでここまでできるのか!」やばいな!と実感する一冊です。これを読まずにただ自力でプログラムを書いている人はもう手遅れになるかもしれません。

Amazonで購入する
エディタ関連
AIエディタCursor完全ガイド

AIエディタCursor完全ガイド ―やりたいことを伝えるだけでできる新世代プログラミング

まだCursor使っていないの?こちらはAI機能が搭載されたエディタです。直近、AIの進化が著しく精度がかなり上がっています。もはや人を超えたと言っても過言ではないでしょう。Cursorを使えばもうプログラミングをすることはほぼなくなります。まだ使っていない方はこちらで使い方を学びましょう。

Amazonで購入する
コード設計関連
良いコード/悪いコードで学ぶ設計入門

良いコード/悪いコードで学ぶ設計入門

初心者にもおすすめ!全エンジニアの良いコードの書き方のバイブルです。2024年12月25日に発売されたばかりの最新版が登場。AI時代でも良い設計は必須スキル。あなたのコーディングスキルが飛躍的に向上することでしょう。

Amazonで購入する