Laravelで作られた掲示板に機能を追加する①の続きです。
目標
- breezeを導入しログイン機能を実装
- ログイン/非ログインで表示を変更する
- リダイレクト先の変更
- ログアウト機能の実装
1. breezeを導入しログイン機能を実装
このサイトを参考にし、breezeをインストールします。
$ composer require laravel/breeze --dev
備忘録的なエラー記録
php artisan breeze:install
すると
Please execute the "npm install && npm run dev" command to build your assets.
というエラーがでるので、
npm install && npm run dev
してみると
bash: npm: command not found
がでたので
$ apt-get install -y npm
してみたら色々インストールされたので
$ npm install && npm run dev
で、インストール成功すると下記が表示されます。
$ node -v
$ npm -v
で両方ともバージョンが表示され、インストールされていることが確認できました。
http://localhost:8000/
にアクセスすると右上にLogin Registerが表示されていました。やったね。
ルーティングの復旧
breezeをインストールするとweb.phpが上書きされていたので、必要な部分のみ復旧します。
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostsController;
use App\Http\Controllers\CommentsController;
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__.'/auth.php';
Route::resource('/bbs', PostsController::class)->parameter('bbs', 'post')->only([
'index', 'show', 'create', 'store', 'edit', 'update', 'destroy'
]);
Route::resource('/comment', CommentsController::class)->only([
'store'
]);
viewファイルの編集
localhostにアクセスするとLogin Registerが表示されているので、それを/bbsにアクセスした時にも表示するようにします。
赤枠の部分が、LaravelPjtBBSにあればいいなという感じです。
<div class="container">
<a class="navbar-brand" href="{{ url('/bbs/') }}">LaravelPjt BBS</a>
</div>
↓ 変更 ↓
<div class="container">
<a class="navbar-brand" href="{{ url('/bbs/') }}">LaravelPjt BBS</a>
@if (Route::has('login'))
<div class="navbar-brand sm:block">
@auth
<div>{{ Auth::user()->name }}</div>
@else
<a href="{{ route('login') }}" class="text-sm text-gray-700 underline">Log in</a>
@if (Route::has('register'))
<a href="{{ route('register') }}" class="ml-4 text-sm text-gray-700 underline">Register</a>
@endif
@endauth
</div>
@endif
</div>
resources\views\welcome.blade.phpをほぼコピペしています。
cssは好みでカスタマイズすればいいので、とりあえずclassはコピペしたまんまを使います。
Log inかRegisterでログインした場合はdashboardでログアウトをして、URLを/dashboardから/bbsに変更します。
右上にLog in Registerが表示されているはずです。
2. ログイン/非ログインで表示を変更する
次に非ログイン時は、新規投稿や編集をさせないように該当箇所を表示しないようにします。
- /bbsのページ
- 新規作成ボタンを非表示
- 編集ボタンを非表示
- 削除ボタンを非表示
- 詳細ページ
- 編集ボタンを非表示
- 削除ボタンを非表示
- コメント入力欄を非表示
(略)
// 新規作成ボタンを非表示
@section('content')
<div class="mt-4 mb-4">
<a href="{{ route('bbs.create') }}" class="btn btn-primary">
投稿の新規作成
</a>
</div>
@if (session('poststatus'))
<div class="alert alert-success mt-4 mb-4">
{{ session('poststatus')}}
</div>
@endif
↓ 変更 ↓
@section('content')
@if (Route::has('login'))
@auth
<div class="mt-4 mb-4">
<a href="{{ route('bbs.create') }}" class="btn btn-primary">
投稿の新規作成
</a>
</div>
@if (session('poststatus'))
<div class="alert alert-success mt-4 mb-4">
{{ session('poststatus')}}
</div>
@endif
@endauth
@endif
(略)
// 編集と削除ボタンを非表示
<p><a href="{{ action('App\Http\Controllers\PostsController@edit', $post->id) }}" class="btn btn-info btn-sm">編集</a></p>
<p>
<form method="POST" action="{{ action('App\Http\Controllers\PostsController@destroy', $post->id) }}">
@csrf
@method('DELETE')
<button class="btn btn-danger btn-sm">削除</button>
</form>
</p>
↓ 変更 ↓
@if (Route::has('login'))
@auth
<p><a href="{{ action('App\Http\Controllers\PostsController@edit', $post->id) }}" class="btn btn-info btn-sm">編集</a></p>
<p>
<form method="POST" action="{{ action('App\Http\Controllers\PostsController@destroy', $post->id) }}">
@csrf
@if (Route::has('login'))
@auth
@method('DELETE')
<button class="btn btn-danger btn-sm">削除</button>
@else
@endauth
@endif
</form>
</p>
@endauth
@endif
これで画像のように新規作成や編集と削除は表示されなくなったはずです。
// 編集と削除ボタンを非表示
(略)
<!-- 編集・編集ボタン -->
<div class="mb-4 text-right">
<a href="{{ action('App\Http\Controllers\PostsController@edit', $post->id) }}" class="btn btn-info">
編集する
</a>
<form
style="display: inline-block;"
method="POST"
action="{{ action('App\Http\Controllers\PostsController@destroy', $post->id) }}"
>
@csrf
@method('DELETE')
<button class="btn btn-danger">削除する</button>
</form>
</div>
↓ 変更 ↓
<!-- 編集・編集ボタン -->
@if (Route::has('login'))
@auth
<div class="mb-4 text-right">
<a href="{{ action('App\Http\Controllers\PostsController@edit', $post->id) }}" class="btn btn-info">
編集する
</a>
<form
style="display: inline-block;"
method="POST"
action="{{ action('App\Http\Controllers\PostsController@destroy', $post->id) }}"
>
@csrf
@method('DELETE')
<button class="btn btn-danger">削除する</button>
</form>
</div>
@else
@endauth
@endif
// コメント入力欄を非表示
(略)
<form class="mb-4" method="POST" action="{{ route('comment.store') }}">
@csrf
<input
name="post_id"
type="hidden"
value="{{ $post->id }}"
>
<div class="form-group">
<label for="subject">
名前
(略)
コメントする
</button>
</div>
</form>
↓ 変更 ↓
@if (Route::has('login'))
@auth
<form class="mb-4" method="POST" action="{{ route('comment.store') }}">
@csrf
<input
name="post_id"
type="hidden"
value="{{ $post->id }}"
>
<div class="form-group">
<label for="subject">
名前
(略)
コメントする
</button>
</div>
</form>
@endauth
@endif
長々と書きましたが、結局は下記のようにif文で囲っただけです。
@if (Route::has('login'))
@auth
ログイン時に表示したい内容
@endauth
@endif
3. リダイレクトの変更
ログインするとdashboardに飛ばされるので、bbsに飛ぶように修正します。
ついでいログアウトのリダイレクト先もbbsに変更します。
public function destroy(Request $request)
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/bbs'); // ← return redirect('/')から変更
}
class RouteServiceProvider extends ServiceProvider
{
/**
* The path to the "home" route for your application.
*
* This is used by Laravel authentication to redirect users after login.
*
* @var string
*/
public const HOME = '/bbs'; // ← return redirect('/dashboard')から変更
4. ログアウト機能の実装
Registerから新規登録(既にアカウントを作った方はLog in)してください。
ログインすると画面右上に名前が表示されているます。
今から画像のように名前の右側にLog Outリンクを作ります。
(本当はdashboardのように名前をクリックするとlog outが表示されるようにしたかったのですが、上手くいきませんでした)
パターン1
formのclass="mb-0"はformがmargin bottomを持っていてレイアウトが崩れたので、それを打ち消すためです。
@if (Route::has('login'))
<div class="navbar-brand sm:block">
@auth
<div class="row">
<div class="text-sm text-gray-700 underline">{{ Auth::user()->name }}</div>
<div class="ml-4 text-sm text-gray-700 underline">
<form class="mb-0" method="POST" action="{{ route('logout') }}">
@csrf
<a href="route('logout')" onclick="event.preventDefault(); this.closest('form').submit();">
{{ __('Log out') }}
</a>
</form>
</div>
</div>
@else
ちなみに上記のコードはdashboard(というかnavigation)のlog out部分(下記)を参考にして書き直しました。
<!-- Authentication -->
<form method="POST" action="{{ route('logout') }}">
@csrf
<x-dropdown-link :href="route('logout')"
onclick="event.preventDefault();
this.closest('form').submit();">
{{ __('Log Out') }}
</x-dropdown-link>
</form>
パターン2
多分よろしくない書き方なのですが、こういう書き方でも動作したので記載しておきます。
@if (Route::has('login'))
<div class="navbar-brand sm:block">
@auth
<div class="row">
<div class="text-sm text-gray-700 underline">{{ Auth::user()->name }}</div>
<div class="ml-4 text-sm text-gray-700 underline"><a href="{{ route('logout') }}">Log out</a></div>
// こちらでも動きます
<!-- <div class="ml-4 text-sm text-gray-700 underline">
@csrf
<form class="mb-0" method="POST" action="{{ route('logout') }}">
<a href="{{ route('logout') }} ">Log out</a>
</form>
</div> -->
</div>
@else
bladeの変更だけだとThe GET method is not supported for this route. Supported methods: POST.
が出るので、ルーティングを追記します。
Laravel 5.xの頃から下記の修正方法があったようです。
Route::get('/logout', [AuthenticatedSessionController::class, 'destroy']); // ←Route::postの上に追記
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
->middleware('auth')
->name('logout');
参考サイト
https://qiita.com/kuroudoart/items/44eca2150f102ba7fdb4
https://dev.classmethod.jp/articles/try-using-auth0-with-php-laravel/
これでBreezeを用いたログイン機能が出来ました。
続きは、Laravelで作られた掲示板に機能を追加する③にて!