58 lines
1.6 KiB
PHP
58 lines
1.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Middleware;
|
|
|
|
use App\Services\EmailOtpService;
|
|
use Closure;
|
|
use Illuminate\Http\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
/**
|
|
* OTP 認証チェックミドルウェア
|
|
*
|
|
* ログイン後、OTP 認証が完了していないユーザーを OTP 入力ページにリダイレクト
|
|
* 24時間以内に OTP 認証が完了している場合はスキップ
|
|
*/
|
|
class EnsureOtpVerified
|
|
{
|
|
protected EmailOtpService $otpService;
|
|
|
|
/**
|
|
* コンストラクタ
|
|
*/
|
|
public function __construct(EmailOtpService $otpService)
|
|
{
|
|
$this->otpService = $otpService;
|
|
}
|
|
|
|
/**
|
|
* リクエストを処理
|
|
*
|
|
* @param Request $request
|
|
* @param Closure $next
|
|
* @return Response
|
|
*/
|
|
public function handle(Request $request, Closure $next): Response
|
|
{
|
|
// ユーザーが認証されていない場合はスキップ
|
|
if (!$request->user()) {
|
|
return $next($request);
|
|
}
|
|
|
|
// OTP ページ関連のリクエストはスキップ(無限ループ防止)
|
|
// /otp /* のパターンを許可
|
|
if ($request->routeIs(['otp.show', 'otp.verify', 'otp.resend'])) {
|
|
return $next($request);
|
|
}
|
|
|
|
// 24時間以内に OTP 認証が完了している場合はスキップ
|
|
if ($this->otpService->isOtpRecent($request->user())) {
|
|
return $next($request);
|
|
}
|
|
|
|
// OTP 認証が必要な場合は OTP ページにリダイレクト
|
|
return redirect()->route('otp.show')
|
|
->with('info', 'セキュリティ確認のため OTP 認証が必要です。');
|
|
}
|
|
}
|