ログイン機能
Laravel Breeze
- Laravel BreezeはLaravelを使ったユーザー登録、ログイン、パスワード再設定、などを手軽に提供してくれるPHPパッケージである。
インストール
- sail composer require laravel/breeze --dev
- sail artisan breeze:install
※ route/web.phpが上書きされるので注意
※ Tailwind CSSもインストールされる
ルーティング
- route/web.phpが更新され、route/auth.phpが追加される。
- ルートはguestミドルウェアとauthミドルウェアのグループに分かれている。
ミドルウェア
ミドルウェアとは
- コントローラのアクションの前後に処理を挟み込むときに使う。
1. sail artisan make:middleware Xxxで生成
public function handle($request, Closure $next)
{
// ここにアクション前に実行させたい処理を書く
$response = $next($request);
// ここにアクション後に実行させたい処理を書く
return $response;
}
2. App\Http\Kernelにミドルウェアを登録する
// グローバルミドルウェアとしてアプリ全体に作用させる場合は$middleware配列に追加する。
protected $middleware = [
\App\Http\Middleware\Xxx::class,
// 以下省略
// ルートミドルウェアとして特定のルートだけに作用させたい場合は$routeMiddleware連想配列に追加する。
(Laravel10からは$middlewareAliases)
protected $middlewareAliases = [
'hoge’ => \App\Http\Middleware\Xxx::class, // ルーティングでhogeを指定すると作用する
// 以下省略
ログイン処理で使われているミドルウェア
guestミドルウェア
- ガードを使ってログイン状況を確認し、ログイン済みの場合はHOMEに飛ばす。
- ガードとは「管理者」「会員」などログイン機構の種類を表す。
ログイン画面の数だけガードがある、というイメージ。 - config/auth.phpに設定があり、driverはログイン状態をどこに保存するか、providerはユーザー情報の取得方法、が定義されている。
authミドルウェア
ログインしていない場合はAuthenticationExceptionを投げ、ログイン画面に飛ばす。
登録・ログイン後、ログアウトのページを変更する
登録・ログイン後
app/Providers/RouteServiceProvider.phpのHOME変更するだけ。public const HOME = '/';
ログアウト後
app/Http/Controllers/Auth/AuthenticatedSessionController.phpのdestroyメソッド内にあるredirect()を修正するだけ。return redirect('/tweet');
ログインユーザーのみに許可する
特定のルーティングをログインユーザーだけに許可する場合は->middleware('auth')
を追加する。
Route::post('/tweet/create', \App\Http\Controllers\Tweet\CreateController::class)
->middleware('auth')
->name('tweet.create');
Route::middleware()
を使うと複数のルートにミドルウェアを指定することができる。
Route::middleware('auth')->group(function () {
// ルート定義
}
テンプレートで@authと@endauthで囲まれた場所はログインユーザーだけに表示される。
@geustと@endguestで囲まれた場所はゲストユーザーだけに表示される。
@auth
<div>
<p>投稿フォーム</p>
@if (session('feedback.success'))
<p style="color: green">{{ session('feedback.success') }}</p>
@endif
<form action="{{ route('tweet.create') }}" method="post">
@csrf
<label for="tweet-content">つぶやき</label>
<span>140文字まで</span>
<textarea id="tweet-content" type="text" name="tweet" placeholder="つぶやきを入力"></textarea>
@error('tweet')
<p style="color: red;">{{ $message }}</p>
@enderror
<button type="submit">投稿</button>
</form>
</div>
@endauth
登録処理にユーザーIDを追加する
ユーザー情報はRequestクラスのuser()メソッドで取得可能。
(Authファサードを使ってAuth::id()でも取得可能)
// 以下を追加
public function userId(): int
{
return $this->user()->id;
}
public function __invoke(CreateRequest $request): Response
{
$tweet = new Tweet();
$tweet->user_id = $request->userId(); // 追加
$tweet->content = $request->tweet();
$tweet->save();
return redirect()->route('tweet.index');
}
自分の登録したデータのみ編集・削除可能とする
サービスクラスに以下を追加。
※ 削除処理でも使うのでコントローラではなくサービスクラスに定義する
public function isOwnTweet(int $userId, int $tweetId): bool
{
$tweet = Tweet::where('id', $tweetId)->first();
if ($tweet === null) {
return false;
}
return $tweet->user_id === $userId;
}
テンプレートに@if (Auth::id() === $tweet->user_id)
の分岐を追加。
<summary>{{ $tweet->content }} by {{ $tweet->user->name }}</summary>
@if (Auth::id() === $tweet->user_id)
<a href="{{ route('tweet.update.index', ['id' => $tweet->id]) }}">編集</a>
<form action="{{ route('tweet.delete', ['id' => $tweet->id]) }}" method="post">
@method('DELETE')
@csrf
<button type="submit">削除</button>
</form>
@else
編集できません
@endif
サービスクラスに追加したメソッドをコントローラで呼び出す。
public function __invoke(Request $request, TweetService $tweetService): View
{
$id = (int)$request->route('id');
if (!$tweetService->isOwnTweet($request->user()->id, $id)) {
throw new AccessDeniedException(); // 403
}
return view('tweet.update', ['tweet' => Tweet::where('id', (int)$request->route('id'))->firstOrFail()]);
}
以下もapp/Http/Controllers/Tweet/Update/IndexController.phpと全く同じ修正をする。
- app/Http/Controllers/Tweet/Update/PutController.php
- app/Http/Controllers/Tweet/Update/DeleteController.php Update/IndexController.php
コメント