234 lines
6.5 KiB
PHP
234 lines
6.5 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Auth;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\Auth;
|
||
use Illuminate\Support\Facades\RateLimiter;
|
||
use Illuminate\Support\Str;
|
||
use Illuminate\Validation\ValidationException;
|
||
|
||
class LoginController extends Controller
|
||
{
|
||
/**
|
||
* ログイン成功後のリダイレクト先
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $redirectTo = '/home';
|
||
|
||
/**
|
||
* コントローラーのインスタンス作成
|
||
* Laravel 12変更点:ミドルウェアは routes/web.php で処理するように変更
|
||
*
|
||
* @return void
|
||
*/
|
||
public function __construct()
|
||
{
|
||
// Laravel 12: ミドルウェアは routes/web.php で処理
|
||
// Laravel 5.7: $this->middleware('guest')->except('logout'); を使用していた
|
||
}
|
||
|
||
/**
|
||
* ログインフォームを表示
|
||
*
|
||
* @return \Illuminate\View\View
|
||
*/
|
||
public function showLoginForm()
|
||
{
|
||
return view('auth.login');
|
||
}
|
||
|
||
/**
|
||
* ログインリクエストを処理
|
||
* Laravel 12変更点:AuthenticatesUsersトレイトを使わず独自実装
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\Response|\Illuminate\Http\JsonResponse
|
||
*/
|
||
public function login(Request $request)
|
||
{
|
||
$this->validateLogin($request);
|
||
|
||
// ログイン試行回数制限チェック
|
||
if ($this->hasTooManyLoginAttempts($request)) {
|
||
$this->fireLockoutEvent($request);
|
||
return $this->sendLockoutResponse($request);
|
||
}
|
||
|
||
// ログイン認証試行
|
||
if ($this->attemptLogin($request)) {
|
||
return $this->sendLoginResponse($request);
|
||
}
|
||
|
||
// ログイン失敗時の処理
|
||
$this->incrementLoginAttempts($request);
|
||
|
||
return $this->sendFailedLoginResponse($request);
|
||
}
|
||
|
||
/**
|
||
* ログインリクエストのバリデーション
|
||
* Laravel 12変更点:ope_id, ope_passフィールドを使用(Laravel 5.7と同じ)
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return void
|
||
*/
|
||
protected function validateLogin(Request $request)
|
||
{
|
||
$request->validate([
|
||
'ope_id' => 'required|string', // オペレータID(旧システムと同じ)
|
||
'ope_pass' => 'required|string', // オペレータパスワード(旧システムと同じ)
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* ログイン認証を試行
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return bool
|
||
*/
|
||
protected function attemptLogin(Request $request)
|
||
{
|
||
return Auth::attempt($this->credentials($request), false);
|
||
}
|
||
|
||
/**
|
||
* 認証用の資格情報を取得
|
||
* Laravel 12変更点:ope_idとope_passをpasswordフィールドにマッピング
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return array
|
||
*/
|
||
protected function credentials(Request $request)
|
||
{
|
||
// Laravel 5.7: ope_id, ope_passをそのまま使用
|
||
// Laravel 12: ope_passをpasswordにマッピングして認証
|
||
return $request->only('ope_id') + ['password' => $request->input('ope_pass')];
|
||
}
|
||
|
||
|
||
/**
|
||
* ログイン成功時のレスポンス
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||
*/
|
||
protected function sendLoginResponse(Request $request)
|
||
{
|
||
$request->session()->regenerate();
|
||
|
||
$this->clearLoginAttempts($request);
|
||
|
||
return redirect()->intended($this->redirectTo);
|
||
}
|
||
|
||
/**
|
||
* ログイン失敗時のレスポンス
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return \Illuminate\Http\RedirectResponse
|
||
*/
|
||
protected function sendFailedLoginResponse(Request $request)
|
||
{
|
||
throw ValidationException::withMessages([
|
||
'ope_id' => [trans('auth.failed')],
|
||
]);
|
||
}
|
||
|
||
/**
|
||
* ログアウト処理
|
||
* Laravel 12変更点:セッション無効化処理を追加
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
|
||
*/
|
||
public function logout(Request $request)
|
||
{
|
||
Auth::logout();
|
||
|
||
// Laravel 12: セッション無効化とトークン再生成を明示的に実行
|
||
$request->session()->invalidate();
|
||
$request->session()->regenerateToken();
|
||
|
||
return redirect('/login');
|
||
}
|
||
|
||
/**
|
||
* ログイン試行回数が上限を超えているかチェック
|
||
* Laravel 12変更点:RateLimiterファサードを使用
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return bool
|
||
*/
|
||
protected function hasTooManyLoginAttempts(Request $request)
|
||
{
|
||
return RateLimiter::tooManyAttempts(
|
||
$this->throttleKey($request), 5
|
||
);
|
||
}
|
||
|
||
/**
|
||
* ログイン試行回数をインクリメント
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return void
|
||
*/
|
||
protected function incrementLoginAttempts(Request $request)
|
||
{
|
||
RateLimiter::hit(
|
||
$this->throttleKey($request), 60
|
||
);
|
||
}
|
||
|
||
/**
|
||
* ログイン試行回数制限をクリア
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return void
|
||
*/
|
||
protected function clearLoginAttempts(Request $request)
|
||
{
|
||
RateLimiter::clear($this->throttleKey($request));
|
||
}
|
||
|
||
/**
|
||
* ロックアウト発生時のイベント処理
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return void
|
||
*/
|
||
protected function fireLockoutEvent(Request $request)
|
||
{
|
||
// 必要に応じてイベントを発火
|
||
}
|
||
|
||
/**
|
||
* レート制限用のスロットルキーを取得
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return string
|
||
*/
|
||
protected function throttleKey(Request $request)
|
||
{
|
||
return Str::lower($request->input('ope_id')).'|'.$request->ip();
|
||
}
|
||
|
||
/**
|
||
* ロックアウト時のレスポンス
|
||
*
|
||
* @param \Illuminate\Http\Request $request
|
||
* @return \Illuminate\Http\RedirectResponse
|
||
*/
|
||
protected function sendLockoutResponse(Request $request)
|
||
{
|
||
$seconds = RateLimiter::availableIn(
|
||
$this->throttleKey($request)
|
||
);
|
||
|
||
throw ValidationException::withMessages([
|
||
'ope_id' => [trans('auth.throttle', ['seconds' => $seconds])],
|
||
]);
|
||
}
|
||
}
|