グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



簡単に迅速に認証機能が作れる Laravel Breeze を理解したい(基本編)

皆様、認証機能はお好きですか?

少し前ですが、ばねさんがLaravelについての記事

を書いていたので、それに乗っかった記事を書いてみようと思ったところ、Breezeというものがありました。

なんだか手軽に簡単に迅速に、つまりBreeze(楽勝)に認証機能が作れちゃう優れもののようです。
理解しておけば今後使えるかも?と思ったので、今回使ってみて分かったことを2回に渡って解説していきたいと思います。

前提

インストール

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から少しカスタマイズをしながら、さらに理解を深めていければと思います。

では、また。

この記事を書いた人

KJG
KJGソリューション事業部 システムエンジニア
大学4年時春に文系就職を辞め、エンジニアになることを決意し、独学でRuby、Ruby on Railsを学習。
約1年間の独学期間を経てアーティスへWebエンジニアとして入社。現在はWebエンジニアとして、主にシステムの開発・運用に従事している。
抽象的なもの、複雑なものを言語化して文章にするのが好きで得意。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします