laravel breeze Multi Auth - Admin Guard с двумя разными регистрациями
Я использую laravel breeze в качестве пакета scaffolding для аутентификации. Я хочу создать множественную аутентификацию с использованием защиты laravel для двух разных форм регистрации для двух типов пользователей (Admin, User) .
Основная идея того, чего я хочу достичь:
У меня есть две таблицы в базе данных: одна для администраторов, а другая - для пользователей, чего я хочу добиться, так это если администраторы решат зарегистрировать учетную запись в качестве администратора, она отобразит форму регистрации с указанными полями для администратора. после этого я хочу проверить, вошел ли пользователь в систему как администратор или пользователь, если он вошел в систему как администратор, перенаправит его / ее на указанную панель инструментов, созданную только для администраторов.
Он отлично работает для регистрации, но не может войти в систему как администратор, вот простое объяснение того, чего я хочу достичь:
приложение \ Models \ Admin.php
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class Admin extends Authenticatable
{
use HasFactory, Notifiable;
protected $table = 'admins';
protected $fillable = [
'name',
'email',
'password',
];
config \ auth.php
<?php
return [
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
// Admin guards
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'admin-api' => [
'driver' => 'token',
'provider' => 'admins',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Admin::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
'throttle' => 60,
],
],
'password_timeout' => 10800,
];
приложение \Http\ Middleware \RedirectIfAuthenticated.php
<?php
namespace App\Http\Middleware;
use App\Providers\RouteServiceProvider;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
public function handle(Request $request, Closure $next, ...$guards)
{
$guards = empty($guards) ? [null] : $guards;
// dd($guards);
foreach ($guards as $guard) {
switch ($guard) {
case 'admin':
if (Auth::guard($guard)->check()) {
return redirect()->route('admin.dashboard');
}
break;
default:
if (Auth::guard($guard)->check()) {
return redirect('/dashboard');
}
break;
}
}
return $next($request);
}
}
routes\web.php
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Admin\RegisteredUserController;
use App\Http\Controllers\Admin\AuthenticatedSessionController;
Route::get('/', function () {
return view('welcome');
});
Route::get('/dashboard', function () {
return view('dashboard');
})->middleware(['auth'])->name('dashboard');
require __DIR__ . '/auth.php';
Route::get('admin/dashboard', function () {
return view('backend.dashboard');
})->middleware(['auth:admin'])->name('admin.dashboard');
Route::get('/admin-register', [RegisteredUserController::class, 'create'])
->middleware('guest:admin')
->name('admin.register');
Route::post('/admin-register', [RegisteredUserController::class, 'store'])
->middleware('guest:admin');
Route::get('/admin-login', [AuthenticatedSessionController::class, 'create'])
->middleware('guest:admin')
->name('admin.login');
Route::post('/admin-login', [AuthenticatedSessionController::class, 'store'])
->middleware('guest:admin');
Route::post('/admin-logout', [AuthenticatedSessionController::class, 'destroy'])
->name('admin.logout')
->middleware('auth:admin');
приложение \Http\ Controllers \ Admin\ AuthenticatedSessionController.php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\LoginRequest;
use App\Providers\RouteServiceProvider;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AuthenticatedSessionController extends Controller
{
public function create()
{
return view('admin.login');
}
public function store(LoginRequest $request)
{
$request->authenticate();
$request->session()->regenerate();
return redirect('admin/dashboard');
}
public function destroy(Request $request)
{
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}
приложение \Http\ Controllers \ Admin\ RegisteredUserController.php
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Admin;
use App\Providers\RouteServiceProvider;
use Illuminate\Auth\Events\Registered;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
class RegisteredUserController extends Controller
{
public function create()
{
return view('admin.register');
}
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|confirmed|min:8',
]);
Auth::login($user = Admin::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]));
event(new Registered($user));
return redirect('admin/dashboard');
}
}
приложение \Http\ Requests \ Admin\ LoginRequest.php
<?php
namespace App\Http\Requests\Admin;
use Illuminate\Auth\Events\Lockout;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;
class LoginRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'email' => 'required|string|email',
'password' => 'required|string',
];
}
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::attempt($this->only('email', 'password'), $this->filled('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
public function ensureIsNotRateLimited()
{
if (! RateLimiter::tooManyAttempts($this->throttleKey(), 5)) {
return;
}
event(new Lockout($this));
$seconds = RateLimiter::availableIn($this->throttleKey());
throw ValidationException::withMessages([
'email' => trans('auth.throttle', [
'seconds' => $seconds,
'minutes' => ceil($seconds / 60),
]),
]);
}
public function throttleKey()
{
return Str::lower($this->input('email')).'|'.$this->ip();
}
}
2 ответа
После трех дней усилий я сам нашел решение.
В функции
authenticate()
в приложении \Http\Requests\Admin\LoginRequest.php. Я заменил
Auth::attempt(...)
к
Auth::guard('admin')->attempt(...)
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (! Auth::guard('admin')->attempt($this->only('email', 'password'), $this->filled('remember'))) {
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
Теперь он отлично работает для входа в систему и регистрации администратора
Хорошо, мой проект немного отличается и не дает 100% ответа, но я решил оставить их здесь, это может кому-то помочь.
приложение / Http / Requests / Auth / LoginRequest.php
public function authenticate()
{
$this->ensureIsNotRateLimited();
if (!Auth::attempt($this->only('email', 'password'), $this->filled('remember')) ||
!auth()->user()->isAdmin() <------------ added
) {
Auth::logout(); <------------ added
RateLimiter::hit($this->throttleKey());
throw ValidationException::withMessages([
'email' => __('auth.failed'),
]);
}
RateLimiter::clear($this->throttleKey());
}
Я добавил функцию isAdmin в модель пользователя, она не встроена заранее