krgm.so-manager-dev.com/app/Http/Controllers/Auth/LoginController.php
你的名字 96c72b9bda
All checks were successful
Deploy main / deploy (push) Successful in 25s
ログインIDは「ope_id」⇒「login_id」に変更
2026-01-06 18:37:45 +09:00

269 lines
8.1 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\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);
}
/**
* ログインリクエストのバリデーション
*
* 仕様上の入力名(フォーム側)は ope_id / ope_pass のまま維持し、
* 内部の認証キーは login_id に寄せるlogin_id 統一)。
*
* @param \Illuminate\Http\Request $request
* @return void
*/
protected function validateLogin(Request $request)
{
// 個別未入力メッセージ仕様1,2
$request->validate([
'ope_id' => 'required|string', // フォームの入力名は現状維持(実体は login_id
'ope_pass' => 'required|string',
], [
'ope_id.required' => 'ログインIDが未入力です。',
'ope_pass.required' => 'パスワードが未入力です。',
]);
}
/**
* ログイン認証を試行
*
*
* - 画面入力ope_id= DBの login_id として扱う
* - 退職フラグチェックも login_id で取得して判定する
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
protected function attemptLogin(Request $request)
{
// 先にIDのみでオペレータ取得して退職フラグを確認仕様5-1
$loginId = $request->input('ope_id'); // 入力名は ope_id だが中身は login_id
$operator = \App\Models\Ope::where('login_id', $loginId)->first();
if ($operator && (int)($operator->ope_quit_flag) === 1) {
// 退職扱いは認証失敗と同じメッセージ仕様5-1 と 3/4 統一表示)
return false;
}
// 認証実行credentials() で login_id / password を渡す)
return Auth::attempt($this->credentials($request), false);
}
/**
* 認証用の資格情報を取得
*
*
* - 認証IDを login_id に統一
* - パスワード入力ope_passは Auth 側の password にマッピング
*
* @param \Illuminate\Http\Request $request
* @return array
*/
protected function credentials(Request $request)
{
return [
'login_id' => $request->input('ope_id'), // フォーム入力ope_id→ DB列 login_id
'password' => $request->input('ope_pass'), // フォーム入力ope_pass→ 認証用 password
];
}
/**
* ログイン成功時のレスポンス
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
// 仕様5: ログインIDをセッション保持
// ここで保持する値も login_id入力名は ope_id のまま)
$request->session()->put('login_ope_id', $request->input('ope_id'));
return redirect()->intended($this->redirectTo);
}
/**
* ログイン失敗時のレスポンス
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse
*/
protected function sendFailedLoginResponse(Request $request)
{
// 画面側のエラー表示キーは仕様に合わせて ope_id のまま
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)
{
// 必要に応じてイベントを発火
}
/**
* レート制限用のスロットルキーを取得
*
*
* - 画面入力名は ope_id のまま
* - ただし内容は login_id を想定ログインID文字列
*
* @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)
);
// 画面側のエラー表示キーは仕様に合わせて ope_id のまま
throw ValidationException::withMessages([
'ope_id' => [trans('auth.throttle', ['seconds' => $seconds])],
]);
}
}