はじめに
Laravelの認証と認可の違い、ミドルウェアの仕組み、ロールを使った権限管理について学習したので、自分用の復習問題としてまとめます。
参考:
① 認証と認可
Q1. 認証(Authentication)と認可(Authorization)の違いは?
答えを見る
- 認証:「あなたは誰か」を確認する
- 認可:「あなたはその操作を実行できるか」を確認する
ログイン確認は認証、管理者だけにユーザー管理を許可するのは認可にあたる。
Q2. 次の2つのコードは、それぞれ何を確認している?
auth()->check();
auth()->user()->isAdmin();
答えを見る
-
auth()->check():ユーザーがログイン済みかを確認する認証のチェック -
isAdmin():ログイン中のユーザーに管理者権限があるかを確認する認可のチェック
Q3. ダッシュボードとユーザー管理ページで必要なチェックはどう違う?
答えを見る
- ダッシュボード:ログイン済みかという認証チェック
- ユーザー管理:ログイン済みかに加え、管理者かという認可チェック
② ミドルウェアの仕組み
Q4. ミドルウェアの役割は?
答えを見る
コントローラーなどの本来の処理にリクエストが到達する前後で、リクエストを検査・加工・拒否する。
認証確認、権限確認、レート制限、ログ記録などに使われる。
Q5. 次の handle() の2つの引数は何?
public function handle(Request $request, Closure $next)
答えを見る
-
$request:ユーザーから受け取ったHTTPリクエスト -
$next:リクエストを次のミドルウェアまたはアプリケーション本体へ渡すコールバック
Q6. 次の3つの戻り値は、それぞれどう動く?
return $next($request);
return redirect('/login');
return abort(403);
答えを見る
-
$next($request):リクエストを次の処理へ渡す -
redirect('/login'):そこで処理を止め、ログインページへリダイレクトする -
abort(403):そこで処理を止め、アクセス権限がないことを示す403レスポンスを返す
Q7. $next($request) の前後に処理を書くと、実行タイミングはどうなる?
// 前処理
$response = $next($request);
// 後処理
return $response;
答えを見る
-
$next($request)の前:リクエストがコントローラーへ到達する前に実行される -
$next($request)の後:次の処理からレスポンスが戻った後に実行される
③ ミドルウェアの適用
Q8. 次の auth ミドルウェアは何をする?
Route::get('/dashboard', [DashboardController::class, 'index'])
->middleware('auth');
答えを見る
ログイン済みユーザーだけにルートへのアクセスを許可する。
未ログインのブラウザリクエストは、通常 login という名前付きルートへリダイレクトされる。
Q9. 複数のルートに同じミドルウェアを適用するにはどう書く?
答えを見る
Route::middleware(['auth'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
Route::get('/profile', [ProfileController::class, 'show']);
Route::get('/settings', [SettingsController::class, 'index']);
});
ルートグループに適用すると、重複した記述を減らせる。
Q10. Laravel 12でコントローラー内にミドルウェアを定義する方法は?
答えを見る
HasMiddleware を実装し、静的な middleware() メソッドから適用したいミドルウェアを返す。
use Illuminate\Routing\Controllers\HasMiddleware;
class DashboardController implements HasMiddleware
{
public static function middleware(): array
{
return ['auth'];
}
}
Q11. カスタムミドルウェアに admin という別名を付ける場所は?
答えを見る
Laravel 12では bootstrap/app.php の withMiddleware() 内で別名を登録する。
use App\Http\Middleware\IsAdmin;
use Illuminate\Foundation\Configuration\Middleware;
->withMiddleware(function (Middleware $middleware): void {
$middleware->alias([
'admin' => IsAdmin::class,
]);
})
登録後は ->middleware('admin') のように利用できる。
④ ロールによる権限管理
Q12. 次のマイグレーションは何を設定する?
$table->enum('role', ['admin', 'user'])
->default('user');
答えを見る
users テーブルに role カラムを追加し、値を admin または user に制限する。
値を指定しない場合は、権限の小さい user がデフォルトになる。
Q13. 次の3つのメソッドはそれぞれ何を判定する?
$user->isAdmin();
$user->hasRole('admin');
$user->hasAnyRole(['admin', 'editor']);
答えを見る
-
isAdmin():ロールがadminか -
hasRole('admin'):ロールが指定した1つのロールと一致するか -
hasAnyRole([...]):指定した複数のロールのいずれかと一致するか
Q14. hasAnyRole() で in_array() の第3引数に true を指定するメリットは?
public function hasAnyRole(array $roles): bool
{
return in_array($this->role, $roles, true);
}
答えを見る
値だけでなく型も含めて厳密に比較し、PHPの暗黙的な型変換による意図しない一致を防げる。
Q15. ユーザー登録処理で、リクエストの role をそのまま保存するとどのような危険がある?
答えを見る
攻撃者がリクエストを改変して role=admin を送信し、自分を管理者として登録できる権限昇格の危険がある。
公開登録画面では role をユーザー入力から受け取らず、DBのデフォルトで user を設定するなどの対策が必要。
Q16. シンプルな role カラムと、Gate・Policyはどのように使い分ける?
答えを見る
-
roleカラム:「管理者か」など、小規模で単純なロール判定に向く - Gate:モデルに紐づかない操作など、比較的単純な認可ルールに向く
- Policy:「その記事を更新できるか」など、モデルやリソースごとの認可ルールの整理に向く
ルールが増える場合は、ミドルウェアに条件を詰め込むだけでなくGateやPolicyも検討する。
まとめ
今回、特に覚えておきたいのは次の5つです。
- 認証は本人確認、認可は操作権限の確認
- ミドルウェアはリクエストを次の処理へ通すか拒否するか判断する
-
$next($request)を呼ぶと次のミドルウェアまたはアプリケーション本体へ進む - Laravel 12のミドルウェア別名は
bootstrap/app.phpで登録する - ロール値を一般ユーザーの入力から保存すると、権限昇格の危険がある