簡単に迅速に認証機能が作れる Laravel Breeze を理解したい(基本編)
皆様、認証機能はお好きですか?
少し前ですが、ばねさんがLaravelについての記事
を書いていたので、それに乗っかった記事を書いてみようと思ったところ、Breezeというものがありました。
なんだか手軽に簡単に迅速に、つまりBreeze(楽勝)に認証機能が作れちゃう優れもののようです。
理解しておけば今後使えるかも?と思ったので、今回使ってみて分かったことを2回に渡って解説していきたいと思います。
前提
- PHP v8.2.10
- Laraval v10.24.0
- Laravel/Breeze v1.23.3
- Laravelアプリケーションをsailで構築済み(詳しくは「今話題のPHPフレームワーク「Laravel」を使ってみた(準備編)」を参考に)
インストール
Laravelアプリケーションができている上でBreezeをインストールする。
$ sail up -d
$ sail composer require laravel/breeze --dev
$ sail php artisan breeze:install
> ミドルウェアを選定する
$ sail php artisan migrate
$ sail npm install
$ sail npm run dev
- http://localhost/
右上に「Log in」と「Register」の文字が出力されていますね。尚それぞれのリンク先に遷移すると、
- http://localhost/register
- http://localhost/login
ごらんの通り、既にできていますね。
では、具体的にコードを見に行きましょう。個人的にあまり見慣れていない箇所に絞って説明をしていきます。尚、コアコードまでは追いませんので悪しからず。。
登録機能の理解
1. routes
# routes/auth.php
Route::middleware('guest')->group(function () {
Route::get('register', [RegisteredUserController::class, 'create'])
->name('register');
Route::post('register', [RegisteredUserController::class, 'store']);
});
Route::middleware(‘guest’)
guest ミドルウェアで現在のユーザーの認証情報を確認して、すでにログイン済みならログイン済みのユーザーが見れるページに、そうでないならログイン画面や登録画面にリダイレクトさせる。2. Controller
# app/Http/Controllers/Auth/RegisteredUserController.php
class RegisteredUserController extends Controller
{
public function create(): View
{
return view('auth.register');
}
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:'.User::class],
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(RouteServiceProvider::HOME);
}
}
$request->validate()
指定されたバリデーションルールに基づいて入力データを検証。もしバリデーションエラーが発生した場合、自動的に前のページにリダイレクトされ、エラーメッセージがセッションに保存される。
event(new Registered($user));
Registeredのイベントを発火させている。デフォルトではこのRegisteredイベントのリスナー等設定されていないので何も起きないが、ウェルカムメールの送信や、統計データの更新などで利用できる。
RouteServiceProvider::HOME
以下のように、 /dashboard を指している。
# app/Providers/RouteServiceProvider.php
class RouteServiceProvider extends ServiceProvider
{
public const HOME = '/dashboard';
~~ 省略 ~~
}
3. view
<!-- resources/views/auth/register.blade.php -->
<form method="POST" action="{{ route('register') }}">
@csrf
<!-- Name -->
<div>
<x-input-label for="name" :value="__('Name')" />
<x-text-input id="name" class="block mt-1 w-full" type="text" name="name" :value="old('name')" required autofocus autocomplete="name" />
<x-input-error :messages="$errors->get('name')" class="mt-2" />
</div>
~~ 省略 ~~
<div class="flex items-center justify-end mt-4">
<a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('login') }}">
{{ __('Already registered?') }}
</a>
<x-primary-button class="ml-4">
{{ __('Register') }}
</x-primary-button>
</div>
</form>
__()
ヘルパ関数で、指定された文字列を現在のロケールに基づいて翻訳した上で表示する。
例えば、 resources/lang/en.json と resources/lang/ja.json が存在し、それぞれ以下のように定義されているとする。
// en.json
{
"Name": "Name",
"Welcome": "Welcome to our application!"
}
// ja.json
{
"Name": "名前",
"Welcome": "私たちのアプリケーションへようこそ!"
}
この場合、 __(‘Name’) はロケールが en の場合は、 “Name” が、 ja の場合は “名前” が表示される。
old()
前回のリクエストから古い入力データを取得する。例えばバリデーションエラーが発生した場合にユーザーが入力した値を再表示する。
ログイン機能の理解
1. routes
# routes/auth.php
Route::middleware('guest')->group(function () {
~~ 省略 ~~
Route::get('login', [AuthenticatedSessionController::class, 'create'])
->name('login');
Route::post('login', [AuthenticatedSessionController::class, 'store']);
~~ 省略 ~~
});
登録機能の理解とあまり変わらないので割愛。
2. Controller
# app/Http/Controllers/Auth/AuthenticatedSessionController.php
class AuthenticatedSessionController extends Controller
{
public function create(): View
{
return view('auth.login');
}
public function store(LoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::HOME);
}
~~ 省略 ~~
}
$request->authenticate(); でユーザー認証を行う。
LoginRequestのauthenticateメソッドが呼び出されて、与えられた認証情報(Eメールとパスワード)がデータベースに存在するユーザー情報と一致するかどうかを確認。
return redirect()->intended(RouteServiceProvider::HOME);
intended() メソッドで、ユーザーがログイン前にアクセスしようとしていたページがあれば、そのページにリダイレクトする。なければ、指定のページにリダイレクトする。3. view
<!-- resources/views/auth/login.blade.php -->
<x-guest-layout>
<!-- Session Status -->
<x-auth-session-status class="mb-4" :status="session('status')" />
<form method="POST" action="{{ route('login') }}">
@csrf
<!-- Email Address -->
<div>
<x-input-label for="email" :value="__('Email')" />
<x-text-input id="email" class="block mt-1 w-full" type="email" name="email" :value="old('email')" required autofocus autocomplete="username" />
<x-input-error :messages="$errors->get('email')" class="mt-2" />
</div>
~~ 省略 ~~
<x-primary-button class="ml-3">
{{ __('Log in') }}
</x-primary-button>
</div>
</form>
</x-guest-layout>
登録機能の理解とあまり変わらないので割愛。
ログアウト機能の理解
1. routes
# routes/auth.php
Route::middleware('auth')->group(function () {
~~ 省略 ~~
Route::post('logout', [AuthenticatedSessionController::class, 'destroy'])
->name('logout');
});
Route::middleware(‘auth’)
認証されていなければログインページに飛ばすだけのミドルウェア。
2. Controller
# app/Http/Controllers/Auth/AuthenticatedSessionController.php
class AuthenticatedSessionController extends Controller
{
~~ 省略 ~~
public function destroy(Request $request): RedirectResponse
{
Auth::guard('web')->logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
Auth::guard(‘web’)->logout();
ガード(guards)は、Laravelの認証の仕組みの中で、「どの方法でユーザーを認証するか?」を定義する役割を持っている。アプリケーションの中で、異なる認証方法やユーザータイプに対応するために利用される。
そのうちの webガード (セッションを使用してユーザーを認証する)を使用し、 logout メソッドを実行している。ここが実質的にログアウト処理。
$request->session()->invalidate();
sessionを無効化し、sessionに入っているデータがクリアされる。
$request->session()->regenerateToken();
ログアウトした後で、セッション固定攻撃を防ぐための安全対策として、新しいセッショントークンを生成し、前のトークンが使われることを防ぐ。
おわりに
以上いかがでしたでしょうか?
コードを見ていく時に見慣れないものがあって、ん?となった箇所も少々ありましたが、比較的理解しやすいようにできている印象でした。Breeze(楽勝)に認証機能を作りたい時にぜひ使ってみようと思います。
次回はこのデフォルトのBreezeから少しカスタマイズをしながら、さらに理解を深めていければと思います。
では、また。
この記事を書いた人
-
大学4年時春に文系就職を辞め、エンジニアになることを決意し、独学でRuby、Ruby on Railsを学習。
約1年間の独学期間を経てアーティスへWebエンジニアとして入社。現在はWebエンジニアとして、主にシステムの開発・運用に従事している。
抽象的なもの、複雑なものを言語化して文章にするのが好きで得意。
この執筆者の最新記事
- 2024年10月8日WEBVue3でjQueryのdatepickerを使いたい!実装手順と注意点を解説します。
- 2024年8月21日WEBVue3の非同期コンポーネントを使ってみる
- 2024年5月28日WEBLaravel×Inertia×Vue3でファイルアップロード機能を作ってみた
- 2024年4月15日WEBLaravel×Inertia×Vue3でCRUD機能を持つSPAを作ってみた
関連記事
最新記事
FOLLOW US
最新の情報をお届けします
- facebookでフォロー
- Twitterでフォロー
- Feedlyでフォロー