krgm.so-manager-dev.com/app/Http/Controllers/Auth/ForgotPasswordController.php
OU.ZAIKOU 5df6c31b86
All checks were successful
Deploy main / deploy (push) Successful in 23s
「パスワード忘れ」修正
2026-01-29 00:02:45 +09:00

113 lines
5.0 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;
class ForgotPasswordController extends Controller
{
// パスワードリセット申請画面表示
public function showLinkRequestForm()
{
return view('auth.forgot-password');
}
// リセットメール送信
public function sendResetLinkEmail(Request $request)
{
$request->validate([
'email' => 'required|email',
'email_confirmation' => 'required|email|same:email',
], [
'email.required' => 'メールアドレスを入力してください。',
'email.email' => '正しいメールアドレス形式で入力してください。',
'email_confirmation.required' => '確認用メールアドレスを入力してください。',
'email_confirmation.email' => '正しいメールアドレス形式で入力してください。',
'email_confirmation.same' => 'メールアドレスが一致しません。',
]);
// ope_mailでユーザーを検索
$user = \App\Models\Ope::where('ope_mail', $request->input('email'))->first();
if (!$user) {
return back()->withErrors(['email' => '該当するユーザーが見つかりません。']);
}
// 5分間隔のメール送信制限チェック最新のトークンを対象
$lastToken = DB::table('password_reset_tokens')
->where('ope_mail', $user->ope_mail)
->orderByDesc('created_at')
->first();
if ($lastToken) {
// タイムゾーンを明示的に指定デフォルトはUTCで解析される可能性がある
$lastCreatedAt = Carbon::parse($lastToken->created_at, config('app.timezone'));
$now = now();
// 経過秒数で判定
$diffSeconds = $lastCreatedAt->diffInSeconds(now(), false);
$limitSeconds = 5 * 60; // 5分
if ($diffSeconds < $limitSeconds) {
$remainSeconds = $limitSeconds - $diffSeconds;
// 残り秒を「分」に変換端数は切り上げ1秒残りでも1分と表示
$waitMinutes = (int) ceil($remainSeconds / 60);
return back()->withErrors([
'email' => "パスワード再設定メールは5分以上の間隔を置いて送信してください。{$waitMinutes}分後に再度お試しください。"
]);
}
}
// トークン生成
$token = Str::random(60);
// SHA256ハッシュで保存セキュリティ向上
$tokenHash = hash('sha256', $token);
// トークン保存(既存レコードがあれば更新)
DB::table('password_reset_tokens')->updateOrInsert(
['ope_mail' => $user->ope_mail],
[
'token' => $tokenHash,
'created_at' => now(),
]
);
// メール送信
try {
$resetUrl = url('/reset-password?token=' . $token . '&email=' . urlencode($user->ope_mail));
$body = $user->ope_name . "\n\n" .
"So-Managerをご利用いただき、ありがとうございます。\n\n" .
"本メールは、パスワード再設定のご依頼を受けてお送りしております。\n\n" .
"以下のURLをクリックし、新しいパスワードを設定してください。\n\n" .
$resetUrl . "\n\n" .
"※このURLの有効期限は、24時間です。\n" .
"※有効期限を過ぎた場合は、再度パスワード再設定手続きを行ってください。\n" .
"※本メールにお心当たりがない場合は、本メールを破棄してください。\n\n" .
"_________________________________\n" .
"So-Manager サポートセンター\n" .
"E-mail : support@so-manager.com\n" .
"URL : https://www.so-manager.com/\n" .
"_________________________________";
Mail::raw($body, function ($message) use ($user) {
$message->to($user->ope_mail)
->from(config('mail.from.address'), config('mail.from.name'))
->subject('【【So-Manager】パスワード再設定のご案内】');
});
} catch (\Throwable $e) {
Log::error('ForgotPassword mail send failed', [
'to' => $user->ope_mail,
'error' => $e->getMessage(),
]);
return back()->withErrors(['email' => 'メール送信に失敗しました。サーバログを確認してください。']);
}
return back()->with('status', 'パスワード再設定メールを送信しました。');
}
}