3

我使用laravel 微风作为身份验证脚手架包。我想使用laravel 保护为两种用户类型(Admin, User)的两种不同注册表单创建多重身份验证。

我想要实现的主要思想:

我在数据库中有两个表,一个用于管理员,另一个用于用户我想要实现的是,如果管理员选择将帐户注册为管理员,它将显示一个带有管理员指定字段的注册表单。之后,我想检查用户是否以管理员身份登录,或者用户是否以管理员身份登录会将他/她重定向到仅为管理员制作的指定仪表板。

它可以很好地注册,但无法以管理员身份登录这里是对我想要实现的目标的简单解释:

应用\模型\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',
    ];

配置\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,

];

app\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');

app\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('/');
        }
    }

app\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();
    }
}
4

2 回答 2

5

经过3天的努力,我自己找到了解决方案。

在app\Http\Requests\Admin\LoginRequest.php的函数authenticate() 中。我已经替换为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());
}

现在它适用于管理员登录和注册

于 2021-02-23T07:40:49.037 回答
2

好的,所以我的项目有点不同,没有给出 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”功能,它不是预先构建的

于 2021-05-15T15:51:34.887 回答