maybe you can reproduce from Laravel Breeze? see https://github.com/laravel/breeze/blob/1.x/stubs/App/Http/Requests/Auth/LoginRequest.php
Jan 13, 2021
4
Level 14
How to limit login attempts using a custom Login controller?
I would like to limit failed login attempts (to avoid brute force) and I wonder if there is a built-in functionality for this in Laravel 8? But I have my own custom Login controller that looks like this... I'm not sure how could I implement this.
class AuthController extends Controller
{
public function login(Request $request)
{
$user = User::whereEmail($request->email)->first();
$credentials = request(['email', 'password']);
if (!Auth::attempt($credentials)) {
return response()->json([
'message' => 'Unauthorized',
]);
}
return response()->json([
'access_token' => $user->createToken('authToken')->plainTextToken,
]);
}
}
Level 14
@coder222 thank you for pointing me to Breeze as it contained exactly what I was looking for. For anyone else looking to do the same here is how I did it.
This limits failed login attempts to 10 per 1 hour. Hope it helps others.
namespace App\Http\Controllers;
use Exception;
use App\Models\User;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
class AuthController extends Controller
{
/**
* Instantiate a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('sanitize')->only(['register']);
}
/**
* Log in a user
*/
public function login(Request $request)
{
$this->checkTooManyFailedAttempts();
$user = User::where('email', $request->email)->first();
try {
$credentials = request(['email', 'password']);
if (!Auth::attempt($credentials))
{
RateLimiter::hit($this->throttleKey(), $seconds = 3600);
return response()->json([
'status_code' => 401,
'message' => 'Unauthorized',
]);
}
if (!Hash::check($request->password, $user->password, [])) {
throw new Exception('Error occured while logging in.');
}
$token = $user->createToken('authToken')->plainTextToken;
RateLimiter::clear($this->throttleKey());
return response()->json([
'status_code' => 200,
'message' => 'Success',
'access_token' => $token,
'token_type' => 'Bearer',
'user' => $user,
]);
} catch (Exception $error) {
return response()->json([
'status_code' => 500,
'message' => 'Error occured while loggin in.',
'error' => $error,
]);
}
}
/**
* Get the rate limiting throttle key for the request.
*
* @return string
*/
public function throttleKey()
{
return Str::lower(request('email')) . '|' . request()->ip();
}
/**
* Ensure the login request is not rate limited.
*
* @return void
*/
public function checkTooManyFailedAttempts()
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 10)) {
return;
}
throw new Exception('IP address banned. Too many login attempts.');
}
}
4 likes
Please or to participate in this conversation.