【Laravelチュートリアル】 STEP6 ログイン認証と利用制限
これまで、Web開発の一通りの流れを学んできました。
この章では、ログイン機能とプログラムの利用制限について学んでいきましょう。
1.ログイン設定
実は、Laravelをインストールしたときからログインに関するものは標準で準備されています。
これらを利用するだけだと非常に簡単になってしまうため、少し実用的なログイン認証を実装していきます。
現在のログイン、ソーシャルログインやSMS承認などログインの方法が多岐に渡ります。
そこでLaravel標準のログインを利用せず、Laravel Fortify
を利用していきます。
ログイン認証の設定を確認しましょう。
// project/config/auth.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that each reset token will be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
/*
|--------------------------------------------------------------------------
| Password Confirmation Timeout
|--------------------------------------------------------------------------
|
| Here you may define the amount of seconds before a password confirmation
| times out and the user is prompted to re-enter their password via the
| confirmation screen. By default, the timeout lasts for three hours.
|
*/
'password_timeout' => 10800,
];
ここにどのようにログインしていくかを設定しています。今回はなにも変更はありません。
データベースの設定も確認しておきましょう。
// project/database/migrations/2014_10_12_000000_create_users_table.php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
laravelがユーザの定義も準備してくれています。
2.Laravel Fortifyを設定
パッケージをインストール
composer require laravel/fortify
コマンドを使用してFortifyのリソースを公開します。
php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
root@537ae07b9b21:/var/workspace/project# php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider"
INFO Publishing assets.
Copying file [vendor/laravel/fortify/stubs/fortify.php] to [config/fortify.php] ............................................................. DONE
Copying file [vendor/laravel/fortify/stubs/CreateNewUser.php] to [app/Actions/Fortify/CreateNewUser.php] .................................... DONE
Copying file [vendor/laravel/fortify/stubs/FortifyServiceProvider.php] to [app/Providers/FortifyServiceProvider.php] ........................ DONE
Copying file [vendor/laravel/fortify/stubs/PasswordValidationRules.php] to [app/Actions/Fortify/PasswordValidationRules.php] ................ DONE
Copying file [vendor/laravel/fortify/stubs/ResetUserPassword.php] to [app/Actions/Fortify/ResetUserPassword.php] ............................ DONE
Copying file [vendor/laravel/fortify/stubs/UpdateUserProfileInformation.php] to [app/Actions/Fortify/UpdateUserProfileInformation.php] ...... DONE
Copying file [vendor/laravel/fortify/stubs/UpdateUserPassword.php] to [app/Actions/Fortify/UpdateUserPassword.php] .......................... DONE
Copying directory [vendor/laravel/fortify/database/migrations] to [database/migrations] ..................................................... DONE
たくさんファイルがコピーされます。
migrationも実行しましょう。
php artisan migrate
2段階認証用のカラム(項目)がusersテーブルに追加されます。
ルートも多く追加されています。
GET|HEAD api/user .................................................................................................................................
GET|HEAD forgot-password .................................................. password.request › Laravel\Fortify › PasswordResetLinkController@create
POST forgot-password ..................................................... password.email › Laravel\Fortify › PasswordResetLinkController@store
GET|HEAD login .................................................................... login › Laravel\Fortify › AuthenticatedSessionController@create
POST login ............................................................................. Laravel\Fortify › AuthenticatedSessionController@store
POST logout ................................................................. logout › Laravel\Fortify › AuthenticatedSessionController@destroy
GET|HEAD register .................................................................... register › Laravel\Fortify › RegisteredUserController@create
POST register ................................................................................ Laravel\Fortify › RegisteredUserController@store
POST reset-password ........................................................... password.update › Laravel\Fortify › NewPasswordController@store
GET|HEAD reset-password/{token} ................................................... password.reset › Laravel\Fortify › NewPasswordController@create
GET|HEAD sanctum/csrf-cookie .................................................... sanctum.csrf-cookie › Laravel\Sanctum › CsrfCookieController@show
GET|HEAD two-factor-challenge ................................. two-factor.login › Laravel\Fortify › TwoFactorAuthenticatedSessionController@create
POST two-factor-challenge ..................................................... Laravel\Fortify › TwoFactorAuthenticatedSessionController@store
GET|HEAD user/confirm-password ............................................................... Laravel\Fortify › ConfirmablePasswordController@show
POST user/confirm-password ........................................... password.confirm › Laravel\Fortify › ConfirmablePasswordController@store
GET|HEAD user/confirmed-password-status .......................... password.confirmation › Laravel\Fortify › ConfirmedPasswordStatusController@show
POST user/confirmed-two-factor-authentication ......... two-factor.confirm › Laravel\Fortify › ConfirmedTwoFactorAuthenticationController@store
PUT user/password ......................................................... user-password.update › Laravel\Fortify › PasswordController@update
PUT user/profile-information ......................... user-profile-information.update › Laravel\Fortify › ProfileInformationController@update
POST user/two-factor-authentication ............................. two-factor.enable › Laravel\Fortify › TwoFactorAuthenticationController@store
DELETE user/two-factor-authentication .......................... two-factor.disable › Laravel\Fortify › TwoFactorAuthenticationController@destroy
GET|HEAD user/two-factor-qr-code ............................................ two-factor.qr-code › Laravel\Fortify › TwoFactorQrCodeController@show
GET|HEAD user/two-factor-recovery-codes ................................ two-factor.recovery-codes › Laravel\Fortify › RecoveryCodeController@index
POST user/two-factor-recovery-codes ............................................................ Laravel\Fortify › RecoveryCodeController@store
GET|HEAD user/two-factor-secret-key ................................... two-factor.secret-key › Laravel\Fortify › TwoFactorSecretKeyController@show
php artisan route:list
のコマンドを実行するとルート一覧が確認できます。ログイン関連の設定は、App\Providers\FortifyServiceProvider
から行います。
configにProviderを追加します。
// project/config/app.php
'providers' => [
// ..
/*
* Package Service Providers...
*/
App\Providers\FortifyServiceProvider::class,
]
エラーが出る場合は、php artisan cache:clear
をしてみてください、
configを確認する。
// project/config/fortify.php
<?php
use Laravel\Fortify\Features;
return [
/*
|--------------------------------------------------------------------------
| Fortify Guard
|--------------------------------------------------------------------------
|
| Here you may specify which authentication guard Fortify will use while
| authenticating users. This value should correspond with one of your
| guards that is already present in your "auth" configuration file.
|
*/
'guard' => 'web',
/*
|--------------------------------------------------------------------------
| Fortify Password Broker
|--------------------------------------------------------------------------
|
| Here you may specify which password broker Fortify can use when a user
| is resetting their password. This configured value should match one
| of your password brokers setup in your "auth" configuration file.
|
*/
'passwords' => 'users',
/*
|--------------------------------------------------------------------------
| Username / Email
|--------------------------------------------------------------------------
|
| This value defines which model attribute should be considered as your
| application's "username" field. Typically, this might be the email
| address of the users but you are free to change this value here.
|
| Out of the box, Fortify expects forgot password and reset password
| requests to have a field named 'email'. If the application uses
| another name for the field you may define it below as needed.
|
*/
'username' => 'email',
'email' => 'email',
/*
|--------------------------------------------------------------------------
| Lowercase Usernames
|--------------------------------------------------------------------------
|
| This value defines whether usernames should be lowercased before saving
| them in the database, as some database system string fields are case
| sensitive. You may disable this for your application if necessary.
|
*/
'lowercase_usernames' => true,
/*
|--------------------------------------------------------------------------
| Home Path
|--------------------------------------------------------------------------
|
| Here you may configure the path where users will get redirected during
| authentication or password reset when the operations are successful
| and the user is authenticated. You are free to change this value.
|
*/
'home' => '/',
/*
|--------------------------------------------------------------------------
| Fortify Routes Prefix / Subdomain
|--------------------------------------------------------------------------
|
| Here you may specify which prefix Fortify will assign to all the routes
| that it registers with the application. If necessary, you may change
| subdomain under which all of the Fortify routes will be available.
|
*/
'prefix' => '',
'domain' => null,
/*
|--------------------------------------------------------------------------
| Fortify Routes Middleware
|--------------------------------------------------------------------------
|
| Here you may specify which middleware Fortify will assign to the routes
| that it registers with the application. If necessary, you may change
| these middleware but typically this provided default is preferred.
|
*/
'middleware' => ['web'],
/*
|--------------------------------------------------------------------------
| Rate Limiting
|--------------------------------------------------------------------------
|
| By default, Fortify will throttle logins to five requests per minute for
| every email and IP address combination. However, if you would like to
| specify a custom rate limiter to call then you may specify it here.
|
*/
'limiters' => [
'login' => 'login',
'two-factor' => 'two-factor',
],
/*
|--------------------------------------------------------------------------
| Register View Routes
|--------------------------------------------------------------------------
|
| Here you may specify if the routes returning views should be disabled as
| you may not need them when building your own application. This may be
| especially true if you're writing a custom single-page application.
|
*/
'views' => true,
/*
|--------------------------------------------------------------------------
| Features
|--------------------------------------------------------------------------
|
| Some of the Fortify features are optional. You may disable the features
| by removing them from this array. You're free to only remove some of
| these features or you can even remove all of these if you need to.
|
*/
'features' => [
Features::registration(),
Features::resetPasswords(),
// Features::emailVerification(),
Features::updateProfileInformation(),
Features::updatePasswords(),
Features::twoFactorAuthentication([
'confirm' => true,
'confirmPassword' => true,
// 'window' => 0,
]),
],
];
'home' => '/'
だけ変更します。これはログイン、新規作成後のリダイレクト先を設定しています。3.ユーザー認証
ログイン画面の設定を行います。
<?php
namespace App\Providers;
use App\Actions\Fortify\CreateNewUser;
use App\Actions\Fortify\ResetUserPassword;
use App\Actions\Fortify\UpdateUserPassword;
use App\Actions\Fortify\UpdateUserProfileInformation;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Laravel\Fortify\Fortify;
class FortifyServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Fortify::createUsersUsing(CreateNewUser::class);
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
RateLimiter::for('login', function (Request $request) {
$throttleKey = Str::transliterate(Str::lower($request->input(Fortify::username())).'|'.$request->ip());
return Limit::perMinute(5)->by($throttleKey);
});
RateLimiter::for('two-factor', function (Request $request) {
return Limit::perMinute(5)->by($request->session()->get('login.id'));
});
Fortify::loginView(function () {
return view('auth.login');
});
}
}
Fortify::loginView
でログイン画面のviewを設定します。テスト用のユーザーデータを作成します。
php artisan make:seeder UsersTableSeeder
// project/database/seeders/UsersTableSeeder.php
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class UsersTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
User::updateOrCreate(['email' => 'local@example.com'], ['name' => 'ララベル 太郎', 'password' => Hash::make('passw@rd'), 'email_verified_at' => now()]);
}
}
ログイン画面を作成します。
// project/resources/views/auth/login.blade.php
@extends('layouts.app')
@section('content')
<div class="login pt-5">
<div class="card mx-auto" style="max-width: 565px;">
<div class="card-body">
<h1 class="text-center">Login</h1>
<form action="{{ route('login') }}" method="POST">
@csrf
<div class="mb-3">
<label for="">ログインID</label>
<input type="email" name="email" class="form-control" value="{{ old('email') }}">
@error('email')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="">パスワード</label>
<input type="password" name="password" class="form-control">
@error('password')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="d-grid gap-2 col-6 mx-auto">
<button type="submit" class="btn btn-primary">ログイン</button>
</div>
</form>
</div>
</div>
</div>
@endsection
4.ユーザの登録
ログイン画面の作成と同様にユーザー作成画面の登録をします。
// project/app/Providers/FortifyServiceProvider.php
use Laravel\Fortify\Fortify;
/**
* 全アプリケーションサービスの起動処理
*/
public function boot(): void
{
// ...
Fortify::registerView(function () {
return view('auth.register');
});
}
レイアウトを作成する。
// project/resources/views/auth/register.blade.php
@extends('layouts.app')
@section('content')
<div class="login pt-5">
<div class="card m-auto" style="max-width: 565px;">
<div class="card-body">
<h1 class="text-center">新規作成</h1>
<form action="{{ route('register') }}" method="POST">
@csrf
<div class="mb-3">
<label for="">名前</label>
<input type="name" name="name" class="form-control" value="{{ old('name') }}">
@error('name')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="">ログインID</label>
<input type="email" name="email" class="form-control" value="{{ old('email') }}">
@error('email')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="">パスワード</label>
<input type="password" name="password" class="form-control">
@error('password')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
<label for="">パスワード確認</label>
<input type="password" name="password_confirmation" class="form-control" placeholder="もう一度パスワードを入力してください">
@error('password_confirmation')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="d-grid gap-2 col-6 mx-auto">
<button type="submit" class="btn btn-primary">新規作成</button>
</div>
</form>
</div>
</div>
</div>
@endsection
ユーザー登録のカスタマイズは、App\Actions\Fortify\CreateNewUser
から変更ができます。
5.パスワードリセット
パスワードリセット用の画面を登録します。
// project/app/Providers/FortifyServiceProvider.php
use Laravel\Fortify\Fortify;
/**
* 全アプリケーションサービスの起動処理
*/
public function boot(): void
{
Fortify::requestPasswordResetLinkView(function () {
return view('auth.forgot-password');
});
// ...
}
// project/resources/views/auth/forgot-password.blade.php
@extends('layouts.app')
@section('content')
<div class="login pt-5">
<div class="card m-auto" style="max-width: 565px;">
<div class="card-body">
<h1 class="text-center">メールを確認</h1>
<p class="text-center text-info">リセット用のメールが届くまで数分お待ちください。メール内のリンクをクリックしてください。リンクの有効期限は1時間です。</p>
<form action="{{ route('password.email') }}" method="POST">
@csrf
<div class="mb-3">
<label for="">ログインID</label>
<input type="email" name="email" class="form-control" placeholder="あなたのメールアドレスを入力してください">
@error('email')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="d-grid gap-2 col-6 mx-auto">
<button type="submit" class="btn btn-primary">メールを送信</button>
</div>
</form>
</div>
</div>
</div>
@endsection
メールを送信するため、.env
の設定が必要です。
今回は、テストのためlog
でメール内容を確認します。
MAIL_MAILER=log
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=info@example.com
MAIL_FROM_NAME="${APP_NAME}"
MAIL_MAILER
とMAIL_FROM_ADDRESS
を設定すればとりあえずOKです。logからリンクを探します。以下のようなリンクが生成されるはずです。
http://localhost:8000/reset-password/14e04df058dd9e855b6e657092a58ecf841d2d14a5a6f4b78fedea5fba20d442?email=local%40example.com
パスワードリセットの画面を作成する
// project/app/Providers/FortifyServiceProvider.php
use Laravel\Fortify\Fortify;
use Illuminate\Http\Request;
/**
* 全アプリケーションサービスの起動処理
*/
public function boot(): void
{
Fortify::resetPasswordView(function (Request $request) {
return view('auth.reset-password', ['request' => $request]);
});
// ...
}
// project/resources/views/auth/reset-password.blade.php
@extends('layouts.app')
@section('content')
<div class="login pt-5">
<div class="card m-auto" style="max-width: 565px;">
<div class="card-body">
@if (session('status'))
<div class="mb-3 alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
<h1 class="text-center">パスワードをリセットします。</h1>
<p class="text-center text-info"></p>
<form action="{{ route('password.update') }}" method="POST">
@csrf
<input type="hidden" name="token" value="{{ request()->route('token') }}">
<div class="mb-3">
<label for="">ログインID</label>
<input type="email" name="email" class="form-control" value="{{ old('email') }}">
@error('email')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="">パスワード</label>
<input type="password" name="password" class="form-control">
@error('password')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
<label for="">パスワード確認</label>
<input type="password" name="password_confirmation" class="form-control" placeholder="もう一度パスワードを入力してください">
@error('password_confirmation')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="d-grid gap-2 col-6 mx-auto">
<button type="submit" class="btn btn-primary">パスワードをリセットする</button>
</div>
</form>
</div>
</div>
</div>
@endsection
ログイン画面にステータスを表示する項目を追加する
@extends('layouts.app')
@section('content')
<div class="login pt-5">
<div class="card m-auto" style="max-width: 565px;">
<div class="card-body">
@if (session('status'))
<div class="mb-3 alert alert-success" role="alert">
{{ session('status') }}
</div>
@endif
<h1 class="text-center">Login</h1>
<form action="{{ route('login') }}" method="POST">
@csrf
<div class="mb-3">
<label for="">ログインID</label>
<input type="email" name="email" class="form-control" value="{{ old('email') }}">
@error('email')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<div class="mb-3">
<label for="">パスワード</label>
<input type="password" name="password" class="form-control">
@error('password')
<div class="invalid-feedback d-block">{{ $message }}</div>
@enderror
</div>
<p>
<a href="{{ route('password.request') }}">パスワードをお忘れですか?</a>
</p>
<div class="d-grid gap-2 col-6 mx-auto">
<button type="submit" class="btn btn-primary">ログイン</button>
</div>
</form>
<hr>
<div class="d-grid gap-2 col-6 mx-auto">
<a href="{{ route('register') }}" class="btn btn-secondary">新規作成</a>
</div>
</div>
</div>
</div>
@endsection
これで、ログイン関連の機能が一通り実装できました。
6.ログアウト
headerにログイン/ログインアウトを追加する
// project/resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{ config('app.name') }}</title>
{{-- ここは、画面に表示されません --}}
@vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
{{-- ここから画面に表示されます。 --}}
<header class="navbar">
<div class="container-fluid">
<h1 class="navbar-brand">{{ config('app.name') }}</h1>
@auth
<form method="post" action="{{ route('logout') }}">
@csrf
<button type="submit" class="btn">ログアウト</button>
</form>
@endauth
@guest
<a href="{{ route('login') }}" class="btn">ログイン</a>
@endguest
</div>
</header>
<div>
<main>
<div class="container">
@yield('content')
</div>
</main>
<footer>
<p>© 2024 laravelチュートリアル</p>
</footer>
</div>
</body>
</html>
7.利用制限をする
投稿一覧、編集、削除を一通りログイン者のみに制限します。
基本的な利用制限はRouteで制限します。
// route/web.php
Route::middleware('auth')->group(function() {
Route::get('/post', [PostController::class, 'index'])->name('post.index');
Route::get('/post/create', [PostController::class, 'create'])->name('post.create');
Route::post('/post/create', [PostController::class, 'store']);
Route::get('/post/{id}', [PostController::class, 'edit'])->name('post.edit');
Route::post('/post/{id}', [PostController::class, 'update']);
Route::get('/post/{id}/delete', [PostController::class, 'destroy'])->name('post.destroy');
});
middleware('auth')
を付けることでログイン者のみに制限できます。group
でルートをまとめることも可能です。もちろんルートに個別で設定することもできます。8.未ログイン者(ゲスト)のページを作成
ゲストのための詳細ページを作成します。
投稿管理とわかるためにArticleController
を作成します。
php artisan make:controller ArticleController
// app/Http/Controllers/ArticleController.php
<?php
namespace App\Http\Controllers;
use App\Models\Post;
use Illuminate\Http\Request;
class ArticleController extends Controller
{
/**
* 投稿詳細ページ
*
* @param string $id
* @return View
*/
public function show($id)
{
$post = Post::find($id);
if ($post == null) {
abort(404);
}
return view('article.show', [
'post' => $post
]);
}
}
// route/web.php
Route::get('article/{id}', [ArticleController::class, 'show'])->name('article.show');
@extends('layouts.app')
@section('content')
<article>
<h1 class="py-3">{{ $post->title }}</h1>
{!! nl2br($post->content) !!}
</article>
@endsection
一覧のページにもリンクを設置していきます。
@extends('layouts.app')
@section('content')
<h1>Hello World</h1>
<div class="mb-3">
<div class="row row-cols-2 g-3">
@foreach($pagination as $post)
<div class="col">
<div class="card h-100">
<div class="card-body">
<h5 class="card-title">{{ $post->title }}</h5>
<p class="card-text">{{ Str::limit($post->content) }}</p>
<div class="text-end">
<a href="{{ route('article.show', ['id' => $post->id]) }}" class="btn btn-primary">詳細へ</a>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
<div class="mb-3">
{{ $pagination->links() }}
</div>
@endsection
今回はログインについて学びました。
Fortify
を利用することで、APIログインや2段階認証など簡単に実装ができるようになるので今回はこれを利用してみました。また、ルートで利用制限の方法についても理解しましたね。
これで大分Webサイトらしくなってきました。