0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

学習ログ #34|LaravelのミドルウェアとTODOアプリ設計を復習するための自分用問題集

0
Posted at

はじめに

Laravelのカスタムミドルウェアと、認証・CRUD・権限管理を統合したTODOアプリの設計について学習したので、自分用の復習問題としてまとめます。

今回は、特に重要な内容を10問に絞って復習します。

参考:


① カスタムミドルウェア

Q1. 次の IsAdmin ミドルウェアは、ユーザーの状態に応じてどう動く?

public function handle(Request $request, Closure $next): Response
{
    if (! auth()->check()) {
        return redirect('/login');
    }

    if (! auth()->user()->isAdmin()) {
        abort(403);
    }

    return $next($request);
}
答えを見る
  • 未ログイン:ログインページへリダイレクトする
  • ログイン済みの一般ユーザー:403 Forbiddenを返す
  • 管理者:$next($request) で次の処理へ進む

Q2. IsAdmin に admin という別名を登録するにはどう書く?

答えを見る

bootstrap/app.php の withMiddleware() で登録する。

use App\Http\Middleware\IsAdmin;
use Illuminate\Foundation\Configuration\Middleware;

->withMiddleware(function (Middleware $middleware): void {
    $middleware->alias([
        'admin' => IsAdmin::class,
    ]);
})

Q3. 次のルート定義は何をする?

Route::middleware(['auth', 'admin'])->group(function () {
    Route::get('/dashboard', function () {
        return view('dashboard');
    });
});
答えを見る

グループ内のルートに、ログイン確認と管理者権限の確認を順番に適用する。

IsAdmin 自体がログイン確認も行う実装なら admin だけでも動くが、auth と権限チェックを分離すると役割が分かりやすい。

Q4. ログイン後のリダイレクト先をロールで分けるだけで、アクセス制御は十分?

答えを見る

不十分。URLを直接入力すれば、リダイレクト先以外のページにもアクセスを試みられるため、各ルート側でもミドルウェアやPolicyによる認可が必要。


② TODOアプリのデータベース設計

Q5. 次の外部キー定義は何をする?

$table->foreignId('user_id')
    ->constrained()
    ->cascadeOnDelete();
答えを見る

tasks.user_id から users.id への外部キー制約を作成する。

ユーザーが物理削除されたときは、そのユーザーに属するタスクもDBによって連鎖削除される。

Q6. statusとpriorityにデフォルト値を設定するメリットは?

$table->enum('status', [
    'pending',
    'in_progress',
    'completed',
])->default('pending');

$table->enum('priority', [
    'low',
    'medium',
    'high',
])->default('medium');
答えを見る

値を指定しなくても、新しいタスクは「未着手」かつ「中優先度」という一貫した状態で登録される。

enum により、DBに保存できる値も指定した候補に制限できる。

Q7. 次のカラムに nullable() が付いている理由は?

$table->text('description')->nullable();
$table->date('due_date')->nullable();
$table->string('image')->nullable();
$table->timestamp('completed_at')->nullable();
答えを見る

説明、期限、画像は必須ではないため。completed_at は、タスクが未完了の間は完了日時が存在しないため null を許可する。


③ モデルとタスクの権限

Q8. User と Task の1対多リレーションはどう定義する?

答えを見る

User モデルでは hasMany() を使う。

public function tasks()
{
    return $this->hasMany(Task::class);
}

Task モデルでは belongsTo() を使う。

public function user()
{
    return $this->belongsTo(User::class);
}

Q9. 一般ユーザーのタスク一覧を、次のように取得するメリットは?

$tasks = auth()->user()
    ->tasks()
    ->latest()
    ->paginate(10);
答えを見る

現在のユーザーと関連するタスクだけがクエリの対象になる。

Task::paginate(10) で全ユーザーのタスクを取得してから画面で隠すより、情報漏えいを防ぎやすい。

Q10. 一般ユーザーは自分のタスクだけ、管理者は全タスクを削除できるようにするには、どのような認可が必要?

答えを見る

削除対象のタスクに対して、次のどちらかを確認する。

  1. ログイン中のユーザーがそのタスクの所有者である
  2. ログイン中のユーザーが管理者である
return $user->isAdmin()
    || $user->id === $task->user_id;

画面上のボタンを隠すだけではなく、Task Policyなどを使ってサーバー側でも必ず確認する。


まとめ

今回、特に覚えておきたいのは次の5つです。

  1. ミドルウェアで未ログインと権限不足を区別する
  2. カスタムミドルウェアは別名を登録するとルートで簡潔に指定できる
  3. ログイン後の画面振り分けだけでなく、ルート側でも認可する
  4. User と Task は hasMany() と belongsTo() の1対多関係
  5. タスクの更新・削除時は、所有者または管理者かをサーバー側で確認する
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?