Laravel Breezeでregister時にメールの送信確認をする
やりたいこと
Laravel Breezeの初期設定だとアカウント新規登録時にメールアドレスの確認をしない。
リンク付きメールでアドレスの確認をしてもらいたい。
smtpサーバーの準備
.envにメールの設定を書いておく。
userコントローラー編集
app/Controllers/user.php
+ use Illuminate\Contracts\Auth\MustVerifyEmail;
- class User extends Authenticatable
+ class User extends Authenticatable implements MustVerifyEmail
{
authをverifiedに変える
routes/web.php
middleware('auth')-> //メール認証前でも通すmiddleware('verified')-> //メール認証前は通さない
問題
プロフィールページでメールアドレスを変更する処理が不親切。
(メールアドレスを変更してから認証メールが送られる。
打ち間違えとかあるから、認証してからメールアドレスを変更したい。)
う~ん。
簡単にやる方法が見つからないから泥臭くやります。
userテーブルに新メールアドレスとトークンを持たせる。
database/migrations/
<?phpuse Illuminate\Database\Migrations\Migration;use Illuminate\Database\Schema\Blueprint;use Illuminate\Support\Facades\Schema;return new class extends Migration{public function up(): void{Schema::table('users', function (Blueprint $table) {$table->string('new_email_token')->after('email')->nullable()->comment('メアド変更用');$table->string('new_email')->after('email')->nullable()->comment('メアド変更用');});}public function down(): void{Schema::table('users', function (Blueprint $table) {$table->dropColumn('new_email_token');$table->dropColumn('new_email');});}};
プロフィールコントローラー
public function update(ProfileUpdateRequest $request): RedirectResponse{$oldMail = auth()->user()->email??null;$newMail = $request->email??null;$request->user()->fill($request->validated());if ($request->user()->isDirty('email')) {$token = generateRandomString(10);$request->user()->email = $oldMail;$request->user()->new_email = $newMail;$request->user()->new_email_token = $token;$url = route('profile.mailUpdate', [auth()->user()->id, $token]);$text = "以下のURLにアクセスしてメールアドレスの変更を完了させてください。・該当アカウントにログイン中のブラウザでアクセスする必要があります。・有効期限は1時間です。$url当メールに心当たりのない場合はこのメールを破棄してください。";Mail::raw($text, function ($message) use ($newMail){$message->to($newMail)->subject('メールアドレスの変更');});$send = 1;}$request->user()->save();return Redirect::route('profile.edit')->with('status', 'profile-updated')->with('send', $send??null);;}// ユーザーのメールアドレスを更新するpublic function mailUpdate(Request $request, $id, $token){$usr = auth()->user();$duplicateCheck = user::where('email', $usr->new_email)->first();$timeLimitCheck = ($usr->updated_at->diffInHours(now()) < 1);//メールアドレス変更if($usr->id == $id&& $usr->new_email_token == $token&& $usr->new_email&& $usr->new_email_token&& !$duplicateCheck&& $timeLimitCheck){$usr->email = $usr->new_email;$usr->new_email = null;$usr->new_email_token = null;$usr->save();$mailStatus = 'メールアドレスを変更しました。';//変更せず}else{$mailStatus = 'メールアドレスを変更できませんでした。';}return Redirect::route('mypage')->with('mailStatus', $mailStatus);}//ランダムな英数字を出力if (!function_exists('generateRandomString')) {function generateRandomString($length = 5) {$characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';$randomString = '';for ($i = 0; $i < $length; $i++) {$randomString .= $characters[rand(0, strlen($characters) - 1)];}return $randomString;}}
メッセージ
@if(session('mailStatus'))
{{session('mailStatus')}}
@endif
@if(session('mailStatus')) {{session('mailStatus')}}@endif@if (session('send'))
<p>※新しいメールアドレスに送られたURLをクリックして変更を完了させてください。</p>
@endif
@if (session('send')) <p>※新しいメールアドレスに送られたURLをクリックして変更を完了させてください。</p>@endifルーティング
Route::middleware(['auth:sanctum', 'verified'])
->get('/mypage/profile/mailupdate/{id}/{token}', [ProfileController::class, 'mailUpdate'])
->name('profile.mailUpdate');
Route::middleware(['auth:sanctum', 'verified']) ->get('/mypage/profile/mailupdate/{id}/{token}', [ProfileController::class, 'mailUpdate']) ->name('profile.mailUpdate');もっとシンプルにできる方法がありましたら更新します。



0件のコメントがあります