Skip to content

Commit

Permalink
login refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
k2so-dev committed Aug 24, 2024
1 parent fedee5a commit 04a561b
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 118 deletions.
49 changes: 21 additions & 28 deletions app/Http/Controllers/AuthController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace App\Http\Controllers;

use App\Http\Requests\Auth\LoginRequest;
use App\Models\User;
use App\Models\UserProvider;
use Browser;
use Illuminate\Auth\Events\PasswordReset;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Events\Verified;
Expand Down Expand Up @@ -114,23 +112,17 @@ public function callback(Request $request, string $provider): View
$user = $userProvider->user;
}

$browser = Browser::parse($request->userAgent());
$device = $browser->platformName() . ' / ' . $browser->browserName();

$sanctumToken = $user->createToken(
$device,
['*'],
now()->addMonth()
$token = $user->createDeviceToken(
device: $request->deviceName(),
ip: $request->ip(),
remember: true
);

$sanctumToken->accessToken->ip = $request->ip();
$sanctumToken->accessToken->save();

return view('oauth', [
'message' => [
'ok' => true,
'provider' => $provider,
'token' => $sanctumToken->plainTextToken,
'token' => $token,
],
]);
}
Expand All @@ -139,29 +131,30 @@ public function callback(Request $request, string $provider): View
* Generate sanctum token on successful login
* @throws ValidationException
*/
public function login(LoginRequest $request): JsonResponse
public function login(Request $request): JsonResponse
{
$user = User::where('email', $request->email)->first();
$request->validate([
'email' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
]);

$request->authenticate($user);
$user = User::select(['id', 'password'])->where('email', $request->email)->first();

$browser = Browser::parse($request->userAgent());
$device = $browser->platformName() . ' / ' . $browser->browserName();
if (!$user || !Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}

$sanctumToken = $user->createToken(
$device,
['*'],
$request->remember ?
now()->addMonth() :
now()->addDay()
$token = $user->createDeviceToken(
device: $request->deviceName(),
ip: $request->ip(),
remember: $request->remember
);

$sanctumToken->accessToken->ip = $request->ip();
$sanctumToken->accessToken->save();

return response()->json([
'ok' => true,
'token' => $sanctumToken->plainTextToken,
'token' => $token,
]);
}

Expand Down
86 changes: 0 additions & 86 deletions app/Http/Requests/Auth/LoginRequest.php

This file was deleted.

16 changes: 16 additions & 0 deletions app/Models/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,20 @@ public function mustVerifyEmail(): bool
{
return $this instanceof MustVerifyEmail && !$this->hasVerifiedEmail();
}

public function createDeviceToken(string $device, string $ip, bool $remember = false): string
{
$sanctumToken = $this->createToken(
$device,
['*'],
$remember ?
now()->addMonth() :
now()->addDay()
);

$sanctumToken->accessToken->ip = $ip;
$sanctumToken->accessToken->save();

return $sanctumToken->plainTextToken;
}
}
33 changes: 31 additions & 2 deletions app/Providers/AppServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace App\Providers;

use App\Helpers\Image;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Auth\Notifications\VerifyEmail;
use Illuminate\Cache\RateLimiting\Limit;
Expand All @@ -11,6 +12,7 @@
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;

class AppServiceProvider extends ServiceProvider
{
Expand Down Expand Up @@ -45,8 +47,26 @@ public function boot(): void
: Limit::perMinute(10)->by($request->ip());
});

RateLimiter::for('login', static function (Request $request) {
return Limit::perMinute(5)
->by(Str::transliterate(implode('|', [
strtolower($request->input('email')),
$request->ip()
])))
->response(static function (Request $request, array $headers): void {
event(new Lockout($request));

throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $headers['Retry-After'],
'minutes' => ceil($headers['Retry-After'] / 60),
]),
]);
});
});

ResetPassword::createUrlUsing(static function (object $notifiable, string $token) {
return config('app.frontend_url') . "/auth/reset/{$token}?email={$notifiable->getEmailForPasswordReset()}";
return config('app.frontend_url') . '/auth/reset/' . $token . '?email=' . $notifiable->getEmailForPasswordReset();
});

VerifyEmail::createUrlUsing(static function (object $notifiable) {
Expand All @@ -65,7 +85,7 @@ public function boot(): void
/**
* Convert uploaded image to webp, jpeg or png format and resize it
*/
UploadedFile::macro('convert', function (?int $width = null, ?int $height = null, string $extension = 'webp', int $quality = 90): UploadedFile {
UploadedFile::macro('convert', function (?int $width = null, ?int $height = null, string $extension = 'webp', int $quality = 90) {
return tap($this, static function (UploadedFile $file) use ($width, $height, $extension, $quality) {
Image::convert($file->path(), $file->path(), $width, $height, $extension, $quality);
});
Expand All @@ -79,5 +99,14 @@ public function boot(): void
// \d matches a digit in any script
return Str::replaceMatches('/[^\p{L}\d ]/u', '', $text);
});

Request::macro('deviceName', function (): string {
$device = $this->device();

return implode(' / ', array_filter([
trim(implode(' ', [$device->getOs('name'), $device->getOs('version')])),
trim(implode(' ', [$device->getClient('name'), $device->getClient('version')])),
])) ?? 'Unknown';
});
}
}
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
"license": "MIT",
"require": {
"php": "^8.2",
"hisorange/browser-detect": "^5.0",
"intervention/image": "^3.4",
"laravel/framework": "^11.0",
"laravel/octane": "^2.3",
"laravel/sanctum": "^4.0",
"laravel/socialite": "^5.12",
"laravel/tinker": "^2.9",
"league/flysystem-aws-s3-v3": "^3.24",
"reefki/laravel-device-detector": "^1.0",
"spatie/laravel-permission": "^6.4"
},
"require-dev": {
Expand Down
2 changes: 1 addition & 1 deletion routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
Route::prefix('api/v1')->group(function () {
Route::get('login/{provider}/redirect', [AuthController::class, 'redirect'])->name('login.provider.redirect');
Route::get('login/{provider}/callback', [AuthController::class, 'callback'])->name('login.provider.callback');
Route::post('login', [AuthController::class, 'login'])->name('login');
Route::post('login', [AuthController::class, 'login'])->middleware('throttle:login')->name('login');
Route::post('register', [AuthController::class, 'register'])->name('register');
Route::post('forgot-password', [AuthController::class, 'sendResetPasswordLink'])->middleware('throttle:5,1')->name('password.email');
Route::post('reset-password', [AuthController::class, 'resetPassword'])->name('password.store');
Expand Down

0 comments on commit 04a561b

Please sign in to comment.