Laravel - Laravel Breeze

提供:MochiuWiki : SUSE, EC, PCB
ナビゲーションに移動 検索に移動

概要

Laravel Breezeは、Laravelフレームワークの認証機能を迅速に実装できるシンプルな認証スターターキットである。

基本的な認証機能として、ログイン/ログアウト、ユーザ登録、パスワードリセット、メール認証等を提供している。
これらの機能は、最小限のコードで実装されており、開発者が理解しやすい構造になっている。

フロントエンドについては、BladeテンプレートエンジンとTailwind CSSの組み合わせが標準である。
ただし、Inertia.jsを使用したVueやReact、あるいは、LivewireとTailwind CSSの組み合わせも選択することができる。
また、APIのみの実装も可能である。

Breezeの特徴は、簡便さとカスタマイズ性にある。
生成されるコードは最小限に抑えられており、必要に応じて機能を追加したり修正したりすることが容易である。

主に、プロトタイプ開発や小規模プロジェクトでの利用に適しているが、スキャフォールディングされたコードを自由に編集できるため、プロジェクトの要件に合わせて柔軟に拡張することができる。

より高度な認証機能やチーム管理機能が必要な場合は、Laravel Jetstreamの使用を推奨する。


Laravel Breezeのインストール

まず、Laravelプロジェクトのトップディレクトリに移動する。
次に、Laravel Breezeをインストールする。

# Laravel Breezeを開発環境の依存関係としてcomposer.jsonのrequire-devセクションに追加する場合
composer require laravel/breeze --dev

# Laravel Breezeのインストール
php artisan breeze:install



ユーザ登録機能の拡張

 
 <?php
 // このPHPファイルは、app/Http/Controllers/Authディレクトリに配置する
 
 namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use App\Models\User;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Validation\Rules;
 use Illuminate\Support\Facades\Password;
 
 class CustomRegistrationController extends Controller
 {
    /**
     * カスタマイズされたユーザ登録処理
     * 標準的なBreezeの登録機能を拡張して、追加情報を保存
     */
    public function store(Request $request)
    {
       try {
          // バリデーションルール
          $request->validate([
             'name' => ['required', 'string', 'max:255'],
             'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
             'password' => ['required', 'confirmed', Rules\Password::defaults()],
             'phone' => ['required', 'string', 'max:20'],
             'birth_date' => ['required', 'date']
          ]);
 
          // ユーザ作成
          $user = User::create([
             'name' => $request->name,
             'email' => $request->email,
             'password' => Hash::make($request->password),
             'phone' => $request->phone,
             'birth_date' => $request->birth_date
          ]);
 
          // ユーザプロフィール情報の作成
          $user->profile()->create([
             'bio' => $request->bio ?? null,
             'address' => $request->address ?? null
          ]);
 
          return redirect()->route('verification.notice');
       }
       catch (\Illuminate\Database\QueryException $e) {
          // データベースエラーの処理
          return back()->withErrors(['db_error' => 'データベース処理中にエラーが発生'])->withInput();
       }
       catch (\Exception $e) {
          // その他の予期せぬエラーの処理
          return back()->withErrors(['error' => '予期せぬエラーが発生'])->withInput();
       }
    }
 }
 ?>



パスワードリセット処理の拡張

 <?php
 // このPHPファイルは、app/Http/Controllers/Authディレクトリに配置する
 
 namespace App\Http\Controllers\Auth;
 
 use App\Http\Controllers\Controller;
 use App\Models\User;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Hash;
 use Illuminate\Validation\Rules;
 use Illuminate\Support\Facades\Password;
 
 class CustomPasswordResetController extends Controller
 {
    /**
     * カスタマイズされたパスワードリセット処理
     * 追加の検証やログ記録機能を実装
     */
    public function store(Request $request)
    {
       try {
          $request->validate([
             'token' => ['required'],
             'email' => ['required', 'email'],
             'password' => ['required', 'confirmed', Rules\Password::defaults()]
          ]);
 
          // パスワードリセットの実行
          $status = Password::reset(
             $request->only('email', 'password', 'password_confirmation', 'token'),
             function ($user, $password) {
                $user->password = Hash::make($password);
                $user->save();
 
                // パスワードリセットのログを記録
                \Log::info("Password reset completed for user: {$user->email}");
             }
          );
 
          if ($status === Password::PASSWORD_RESET) {
             return redirect()->route('login')->with('status', __($status));
          }
 
          return back()->withErrors(['email' => __($status)]);
       }
       catch (\Exception $e) {
          \Log::error("Password reset failed: {$e->getMessage()}");
          return back()->withErrors(['error' => 'パスワードリセット処理中にエラーが発生しました。']);
       }
    }
 }
 ?>



カスタムミドルウェア

 <?php
 // このPHPファイルは、app/Http/Middlewareディレクトリに配置する
 // また、このファイル (ミドルウェア) を使用する場合は、app/Http/Kernel.phpに登録する必要があることに注意する
 
 namespace App\Http\Middleware;
 
 use Closure;
 use Illuminate\Http\Request;
 
 class CheckProfileCompletion
 {
    /**
     * プロフィール完了状態を確認するミドルウェア
     * 必須項目が未入力の場合はプロフィール編集ページにリダイレクト
     */
    public function handle(Request $request, Closure $next)
    {
       if (auth()->check() && !auth()->user()->hasCompletedProfile()) {
          return redirect()->route('profile.edit')->with('warning', 'プロフィールの入力を完了してください');
       }
 
       return $next($request);
    }
 }
 ?>


 <?php
 // このPHPファイルは、app/Modelsディレクトリに配置する
 
 // Userモデルの拡張
 namespace App\Models;
 
 use Laravel\Sanctum\HasApiTokens;
 use Illuminate\Foundation\Auth\User as Authenticatable;
 
 class User extends Authenticatable
 {
    use HasApiTokens;
 
    protected $fillable = [
       'name',
       'email',
       'password',
       'phone',
       'birth_date'
    ];
 
    /**
     * プロフィールの完了状態をチェック
     */
    public function hasCompletedProfile(): bool
    {
       return !empty($this->phone) && !empty($this->birth_date) &&  $this->profile()->exists();
    }
 
    /**
     * プロフィールとのリレーション定義
     */
    public function profile()
    {
       return $this->hasOne(Profile::class);
    }
 }
 ?>



APIトークン管理

 <?php
 // このPHPファイルは、app/Http/Controllers/Apiディレクトリに配置する
 
 namespace App\Http\Controllers\Api;
 
 use App\Http\Controllers\Controller;
 use Illuminate\Http\Request;
 
 class TokenController extends Controller
 {
    /**
     * APIトークンの生成
     * Breezeのデフォルト認証と組み合わせてAPI認証を実装
     */
    public function createToken(Request $request)
    {
       try {
          $request->validate([
             'token_name' => 'required|string|max:255'
          ]);
 
          $token = $request->user()->createToken($request->token_name);
 
          return response()->json([
             'token' => $token->plainTextToken
          ]);
       }
       catch (\Exception $e) {
          return response()->json([
             'error' => 'トークン生成中にエラーが発生'
          ], 500);
       }
    }
 }
 ?>