Breeze
インストール
Laravelアプリケーションができた上でインストールする
$ sail composer require laravel/breeze --dev
Breezeの必要なファイル達をアプリケーション内のそれぞれの適切な場所に公開する
$ sail php artisan breeze:install
> ミドルウェアを選定できる
Breezeで使うUserテーブルをDBにマイグレートする
$ sail php artisan migrate
BreezeやLaravelが依存しているJavaScriptのライブラリやパッケージをインストール
$ sail npm install
デフォルトのスタイリングやJavaScriptの動作をプロジェクトに反映
$ sail npm run dev
画面の日本語化
/resources/views/auth/
以下のviewファイル内に存在する {{ __('XXXXX')}}
部分に日本語が入ってくるように対応する
ロケールの変更
# /config/app.php
...省略...
'locale' => 'ja', // ここを変更
...省略...
/lang/ja.json
上記ディレクトリとファイルを作成し、以下を追記
// /lang/ja.json
{
"Log in": "ログイン",
"Password": "パスワード",
"Email": "メールアドレス",
"Forgot your password?": "パスワードをお忘れですか?",
"Remember me": "パスワードを保存する",
"Name": "名前",
"Confirm Password":"パスワードの確認",
"Already registered?":"登録済ですか?",
"Register":"登録"
}
ライブラリの利用
以下のコマンドを叩く
$ composer require askdkc/breezejp --dev
$ php artisan breezejp
timezoneやlocaleが変わりつつ、langディレクトリが作成され、その中にja.json
等のファイルが作成される
ユーザ名でログインできるように
認証バリデーションを変更
rules()
メソッド内を変更した上で、同ファイルの他のemail
と記述がある部分をname
に変更
// /app/Http/Requests/Auth/LoginRequest.php
class LoginRequest extends FormRequest
{
...省略...
public function rules(): array
{
return [
'name' => ['required', 'string'], // ここを変更
'password' => ['required', 'string'],
];
}
...省略...
}
Viewの変更
email
と記載のある部分をname
に変更
日本語化してあれば、:value="__('Name')"
で、してなければ value="お名前"
# /resources/views/auth/login.blade.php
...省略...
<!-- Email Address -->
<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="username" />
<x-input-error :messages="$errors->get('name')" class="mt-2" />
</div>
...省略...
電話番号も登録する
Viewの対応
// /resources/views/auth/register.blade.php
...省略...
<!-- Phone -->
<div class="mt-4">
<x-input-label for="phone" :value="__('Phone')" />
<x-text-input id="phone" class="block mt-1 w-full"
type="text"
name="phone"
:value="old('phone')"
required
autocomplete="username" />
<x-input-error :messages="$errors->get('phone')" class="mt-2" />
</div>
...省略...
日本語化対応する
// /lang/ja.json
{
...省略...
"Phone": "電話番号", // ここを追加
...省略...
}
マイグレーションの対応
users
テーブルに電話番号フィールドを追加する新しいマイグレーションを作成する
$ php artisan make:migration add_phone_field_to_users_table
# /database/migrations/YYYY_mm_dd_HHiiss_add_phone_field_to_users_table.php
return new class extends Migration
{
...省略...
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('phone')->nullable();
});
}
...省略...
};
$ php artisan migrate
コントローラーの対応
# /app/Http/Controllers/Auth/RegisteredUserController.php
class RegisteredUserController extends Controller
{
...省略...
public function store(Request $request): RedirectResponse
{
$request->validate([
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'lowercase', 'email', 'max:255', 'unique:'.User::class],
'phone' => ['required', 'string', 'max:255'], // ここを追加
'password' => ['required', 'confirmed', Rules\Password::defaults()],
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'phone' => $request->phone, // ここを追加
'password' => Hash::make($request->password),
]);
event(new Registered($user));
Auth::login($user);
return redirect(RouteServiceProvider::HOME);
}
}
モデルの対応
# /app/Models/User.php
class User extends Authenticatable
{
...省略...
protected $fillable = [
'name',
'email',
'phone', // ここを追加
'password',
];
...省略...
}
メール認証を有効にする
MustVerifyEmailインターフェースを実装
# /app/Models/User.php
use Illuminate\Contracts\Auth\MustVerifyEmail; // ここを追加
class User extends Authenticatable implements MustVerifyEmail // ここを変更
{
...省略...
}
routeの対応
認証されていないユーザーへのアクセスを制限するミドルウェアを追加する
authミドルウェアはゲストからのアクセスを防ぐ、verifiedミドルウェアはメールを認証したかどうかチェックする
# /app/Models/User.php
Route::get('/only-verified', function () {
return view('only-verified');
})->middleware(['auth', 'verified']); // ここを追加
Mailpitで確認
http://localhost:8025/ にアクセスすることで確認できる
マルチ認証(Multi Authentication)
adminsとmembersのようにひとつのアプリケーションで2つの別のシステムを扱う時や機能を提供する時に、それぞれのシステムにログインできる人=その機能を使える人を制御したい時に実装する。
モデル作成(=DBテーブルの作成)
マイグレーションファイルを作成しながらモデルを作成する
$ php artisan make:model Admin -m
Userモデルの内容をAdminモデルにコピペ(クラス名はAdminに変更)
User用のマイグレーションファイルの内容をAdmin用のマイグレーションファイルにコピペ
DBテーブルの作成
$ php artisan migrate
ガード(Guard)の設定
Laravelにアクセスするリクエストに対してガードする(守る)役目を持っている。
どのロールにおいての認証であるかを表現するのに使う(Laravelではguardとして表現するのが自然)
/config/auth.php
に追記する
URLでどのロールかを判別する
/member
は会員向けの機能、/admin
は管理者向けの機能を提供するとして、/app/detect_role.php
というヘルパーを作成する
# /app/detect_role.php
<?php
use Illuminate\Support\Str;
if (!function_exists('detect_role')) {
function detect_role(): ?string
{
$current_uri = request()->path();
$roles = ['member', 'admin'];
foreach ($roles as $role) {
if (Str::startsWith($current_uri, $role)) {
return $role;
}
}
return null;
}
}
登録したヘルパー関数をどこでも使えるようにする
// /composer.json
{
... 省略 ...
"autoload": {
"files": [
"app/detect_role.php"
],
... 省略 ...
},
... 省略 ...
}
routesの設定
/routes/member.php
と/routes/admin.php
を作成する
/routes/web.php
の認証関連の記述箇所を移行しながら、PrefixとMiddlewareを設定しながらグループ化する
# /routes/member.php
<?php
use App\Http\Controllers\ProfileController;
use Illuminate\Support\Facades\Route;
Route::prefix('member')->name('member.')->group(function () {
Route::middleware(['auth:member'])->group(function () {
Route::get('/dashboard', function () {
return view('Member/dashboard');
})->middleware(['auth', 'verified'])
->name('dashboard');
Route::middleware('auth')->group(function () {
Route::get('/profile', [ProfileController::class, 'edit'])->name('profile.edit');
Route::patch('/profile', [ProfileController::class, 'update'])->name('profile.update');
Route::delete('/profile', [ProfileController::class, 'destroy'])->name('profile.destroy');
});
});
require __DIR__ . '/auth.php';
});
Controllerの設定
共通利用箇所を親クラスで用意する。
それぞれのAuth以下のコントローラーはこのクラスを継承する。
# /app/Http/Controllers/Auth/AuthController.php
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Support\Str;
class AuthController extends Controller
{
private ?string $role;
private string $package;
public function __construct()
{
$this->role = detect_role();
if (empty($this->role)) {
$this->package = '';
} else {
$camel = Str::camel($this->role);
$camel[0] = strtoupper($camel[0]);
$this->package = $camel;
}
}
}
全ロールでAuth以下のコントローラーを利用できるように以下5か所を修正する。
HOMEの設定
# /app/Providers/RouteServiceProvider.php
class RouteServiceProvider extends ServiceProvider
{
... 省略 ...
private const HOME = '/dashboard';
public static function home() { // ここを追加
$role = detect_role();
return empty($role) ? self::HOME : '/' . $role . self::HOME;
}
... 省略 ...
}
# /app/Http/Controllers/Auth/AuthenticatedSessionController.php
public function store(LoginRequest $request): RedirectResponse
{
$request->authenticate();
$request->session()->regenerate();
return redirect()->intended(RouteServiceProvider::home()); // ここを変更
}
ルーティングの対応
# /app/Http/Controllers/Auth/NewPasswordController
public function store(Request $request): RedirectResponse
{
... 省略 ...
if ($status == Password::PASSWORD_RESET) {
return redirect()->route($this->route('login'))->with('status', __($status)); // ここを変更
}
... 省略 ...
}
# /app/Http/Controllers/Auth/AuthController.php
<?php
... 省略 ...
class AuthController extends Controller
{
... 省略 ...
public function route($route): string // ここを追加
{
if (empty($this->role)) {
return $route;
}
return $this->role . '.' . $route;
}
... 省略 ...
}
レンダリングするリソース名の対応
Laravel Breeze認証 でログイン後に遷移するページをカスタマイズする
public const HOME = '/home';