Skip to content

Commit b1b183d

Browse files
committed
feat: update two-factor authentication to delay login until confirmation
1 parent ea4d231 commit b1b183d

File tree

3 files changed

+21
-25
lines changed

3 files changed

+21
-25
lines changed

app/Http/Controllers/Auth/AuthenticatedSessionController.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Illuminate\Support\Facades\Route;
1111
use Inertia\Inertia;
1212
use Inertia\Response;
13+
use Laravel\Fortify\Features;
1314

1415
class AuthenticatedSessionController extends Controller
1516
{
@@ -29,7 +30,18 @@ public function create(Request $request): Response
2930
*/
3031
public function store(LoginRequest $request): RedirectResponse
3132
{
32-
$request->authenticate();
33+
$user = $request->validateCredentials();
34+
35+
if (Features::enabled(Features::twoFactorAuthentication()) && filled($user->two_factor_confirmed_at)) {
36+
$request->session()->put([
37+
'login.id' => $user->getKey(),
38+
'login.remember' => $request->boolean('remember'),
39+
]);
40+
41+
return redirect()->route('two-factor.login');
42+
}
43+
44+
Auth::login($user, $request->boolean('remember'));
3345

3446
$request->session()->regenerate();
3547

app/Http/Requests/Auth/LoginRequest.php

Lines changed: 7 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,9 @@
66
use Illuminate\Auth\Events\Lockout;
77
use Illuminate\Foundation\Http\FormRequest;
88
use Illuminate\Support\Facades\Auth;
9-
use Illuminate\Support\Facades\Hash;
109
use Illuminate\Support\Facades\RateLimiter;
1110
use Illuminate\Support\Str;
1211
use Illuminate\Validation\ValidationException;
13-
use Laravel\Fortify\Features;
1412

1513
class LoginRequest extends FormRequest
1614
{
@@ -36,34 +34,18 @@ public function rules(): array
3634
}
3735

3836
/**
39-
* Attempt to authenticate the request's credentials.
37+
* Validate the request's credentials and return the user without logging them in.
4038
*
4139
* @throws \Illuminate\Validation\ValidationException
4240
*/
43-
public function authenticate()
41+
public function validateCredentials(): User
4442
{
4543
$this->ensureIsNotRateLimited();
4644

47-
// Check if two-factor authentication is enabled
48-
if (Features::enabled(Features::twoFactorAuthentication())) {
49-
$user = User::where('email', $this->email)->first();
45+
/** @var User $user */
46+
$user = Auth::getProvider()->retrieveByCredentials($this->only('email', 'password'));
5047

51-
// If this user exists, the password is correct, and 2FA is enabled; we want to redirect to the 2FA challenge
52-
if ($user && $user->two_factor_confirmed_at && Hash::check($this->password, $user->password)) {
53-
// Store the user ID and remember preference in the session
54-
$this->session()->put([
55-
'login.id' => $user->getKey(),
56-
'login.remember' => $this->boolean('remember'),
57-
]);
58-
59-
RateLimiter::clear($this->throttleKey());
60-
61-
return redirect()->route('two-factor.login');
62-
}
63-
}
64-
65-
// Proceed with normal authentication if 2FA is not enabled or the user doesn't have 2FA
66-
if (! Auth::attempt($this->only('email', 'password'), $this->boolean('remember'))) {
48+
if (! $user || ! Auth::getProvider()->validateCredentials($user, $this->only('password'))) {
6749
RateLimiter::hit($this->throttleKey());
6850

6951
throw ValidationException::withMessages([
@@ -72,6 +54,8 @@ public function authenticate()
7254
}
7355

7456
RateLimiter::clear($this->throttleKey());
57+
58+
return $user;
7559
}
7660

7761
/**

app/Providers/FortifyServiceProvider.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public function boot(): void
2525
return Inertia::render('auth/ConfirmPassword');
2626
});
2727

28-
RateLimiter::for('login', function (Request $request) {
28+
RateLimiter::for('login', function (Request $request) {
2929
$throttleKey = Str::transliterate(Str::lower((string) $request->string(Fortify::username())).'|'.$request->ip());
3030

3131
return Limit::perMinute(5)->by($throttleKey);

0 commit comments

Comments
 (0)