サイトアイコン IT & ライフハックブログ|学びと実践のためのアイデア集

Laravelの認証と認可入門:ログイン後のルート保護とGateを基礎から学ぶ

php elephant sticker

Photo by RealToughCandy.com on Pexels.com

Laravelでログイン機能を用意しても、それだけでは利用者ごとの操作範囲まで制御できません。

安全なWebアプリケーションには、利用者を確かめる認証と、許可する操作を決める認可の両方が必要です。

この記事では、認証済みの利用者だけに画面を開く方法と、投稿を編集できる利用者をGateで判定する方法を、フォームのアクセシビリティとあわせて説明します。

この記事で学べること

認証と認可の違い

認証は、アクセスしている利用者が誰かを確認する仕組みです。

認可は、確認できた利用者にどの操作を許すかを判定する仕組みです。

仕組み 答える問い 例
認証 誰が利用しているか ログイン、ログアウト、パスワード再設定
認可 何をしてよいか 自分の投稿だけを編集する、管理画面を管理者だけに見せる

たとえば、ログイン済みであることは「すべての投稿を編集してよい」ことを意味しません。

認証で利用者を特定したあと、対象データと操作ごとに認可を判定します。

作業前にLaravelのバージョンを確認する

Laravelの導入手順とファイル構成は、利用するバージョンとスターターキットによって変わります。

旧版向けのBreeze導入手順をそのまま実行せず、作業対象に合うLaravel公式のスターターキット情報を確認してください。

新規プロジェクトの作成例は次のとおりです。

composer ​global ​require ​laravel/installer
laravel ​new ​myapp

cd ​myapp
npm ​install ​&& ​npm ​run ​build
composer ​run ​dev

プロジェクト作成時に選ぶ構成によって認証画面の実装場所が異なるため、この記事では特定の画面ファイルに依存しない認証と認可の基礎を扱います。

バージョン選定や運用まで含めて検討する場合は、PHPとLaravelで業務Webアプリを作る前に決めることも参考になります。

authミドルウェアで認証済みの利用者だけに開く

ミドルウェアは、リクエストが処理へ届く前に条件を確認する仕組みです。

Laravelのauthミドルウェアをルートへ付けると、認証済みの利用者だけがそのルートへ進めます。

use ​Illuminate\Support\Facades\Route;

Route::middleware('auth')->group(function ​() ​{
 ​ ​ ​ ​Route::get('/dashboard', ​function ​() ​{
 ​ ​ ​ ​ ​ ​ ​ ​return ​view('dashboard');
 ​ ​ ​ ​});
});

この例では/dashboardを保護できますが、投稿の所有者までは判定していません。

authは入口の確認に使い、個別の操作権限はGateまたはPolicyで判定します。

Gateで投稿の編集権限を判定する

Gateは、利用者が特定の操作を実行できるかを真偽値で表す認可ルールです。

次の例では、ログイン中の利用者IDと投稿の作成者IDが一致するときだけ、更新を許可します。

use ​App\Models\Post;
use ​App\Models\User;
use ​Illuminate\Support\Facades\Gate;

public ​function ​boot(): ​void
{
 ​ ​ ​ ​Gate::define('update-post', ​function ​(User ​$user, ​Post ​$post): ​bool ​{
 ​ ​ ​ ​ ​ ​ ​ ​return ​$user->id ​=== ​$post->user_id;
 ​ ​ ​ ​});
}

GateはApp\Providers\AppServiceProviderのbootメソッドで定義できます。

コントローラーでは、更新処理の前に同じルールを呼び出します。

use ​App\Models\Post;
use ​Illuminate\Support\Facades\Gate;

public ​function ​edit(Post ​$post)
{
 ​ ​ ​ ​Gate::authorize('update-post', ​$post);

 ​ ​ ​ ​return ​view('posts.edit', ​compact('post'));
}

権限がない場合は処理を先へ進めず、Laravelが認可エラーをHTTP ​403レスポンスへ変換します。

Gateの定義方法と判定方法は、Laravel公式の認可ドキュメントで確認できます。

GateとPolicyの使い分け

認可ルールが増えたら、対象とルールのまとまりを見て配置を決めます。

方法 向いている場面
Gate 管理画面の閲覧など、単発の操作を小さなルールとして表したいとき
Policy 投稿の閲覧、更新、削除など、一つのモデルに関する複数のルールをまとめたいとき

最初はGateで認可の流れを理解し、投稿に関する判定が増えた段階でPolicyへ整理すると役割を追いやすくなります。

ログインフォームを理解しやすくする

ログインフォームでは、入力欄の目的、必須かどうか、エラーの内容を見た目とプログラムの両方から把握できるようにします。

<label ​for='email'>メールアドレス(必須)</label>
<input
 ​ ​ ​ ​id='email'
 ​ ​ ​ ​type='email'
 ​ ​ ​ ​name='email'
 ​ ​ ​ ​value='{{ ​old('email') ​}}'
 ​ ​ ​ ​required
 ​ ​ ​ ​@error('email') ​aria-invalid='true' ​aria-describedby='email-error' ​@enderror
>

@error('email')
 ​ ​ ​ ​<p ​id='email-error' ​role='alert'>{{ ​$message ​}}</p>
@enderror

フォーム部品を共通化するときは、ラベルやエラー関連付けを呼び出し側が欠落させない設計にします。

再利用設計はLaravelのBladeコンポーネントによるUI部品設計、操作確認はキーボード操作とフォーカス表示の実務で詳しく確認できます。

フォームのラベルとエラー通知の考え方は、W3C ​WAIのフォームチュートリアルにも整理されています。

実装後に確認する順序

  1. 対象プロジェクトのLaravelバージョンとスターターキットを確認する
  2. ログイン、ログアウトなど必要な認証ルートを確認する
  3. 認証が必要なルートへauthミドルウェアを付ける
  4. 対象データと操作ごとにGateまたはPolicyを定義する
  5. 未認証、認証済み、所有者、所有者以外の各状態をテストする
  6. フォームをキーボードと支援技術で確認する

初心者が見落としやすい点

認証と認可を分けて設計する

Laravelの認証は利用者を特定し、認可はその利用者に許す操作を判定します。

authミドルウェアで入口を守り、GateまたはPolicyで対象ごとの操作を制御し、フォームでは入力方法とエラーを明確に伝えることが実装の基本です。

最初に「誰が、どのデータへ、どの操作をできるか」を表にしてからコードへ落とすと、認可ルールの漏れを見つけやすくなります。

この記事に関連する株式会社greedenの取り組み

認証と認可を正しく分けても、業務ルールを画面と権限設計へ落とし込めなければ、安全で使いやすいサービスにはなりません。株式会社greedenは、要件整理から実装、テスト、保守改善まで一貫したWebシステム開発を支援します。

モバイルバージョンを終了