У меня установлена система множественной аутентификации в Laravel 5.7
На сайте есть раздел «Администратор» и раздел «Ученик».
Когда вы пытаетесь получить доступ к части какого-либо сайта, он перенаправляет вам правильную страницу входа, если вы еще не вошли в систему.
Однако, если выполнить эти шаги, я столкнусь с проблемой с перенаправлениями:
Он правильно регистрирует меня, но неправильно перенаправляет на другую страницу входа.
Проблема также происходит наоборот, если я получу автоматическое перенаправление на «ученика», то сделайте ссылку непосредственно на страницу входа администратора и войдите в систему.
Я полагаю, что сузил проблему до неаутентифицированной функции, которую я поместил в файл Exception / Handler.php, но я не могу понять, куда идти дальше.
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'learner':
$login = 'learner.login';
break;
default:
$login = 'login';
break;
}
return redirect()->guest(route($login));
}
Использование каждой отдельной страницы входа работает нормально. Просто когда вы следите за процессом выше, я вижу проблемы.
Я использую отдельное промежуточное программное обеспечение в каждом контроллере, как это:
Admin Home Controller
public function __construct()
{
$this->middleware('auth');
}
Контроллер входа администратора:
public function __construct()
{
$this->middleware('guest')->except('logout');
}
Домашний контроллер ученика
public function __construct()
{
$this->middleware('auth:learner');
}
Контроллер входа ученика:
public function __construct()
{
$this->middleware('guest:learner')->except('logout');
}
Решение: очистка предполагаемого URL с помощью сеанса: забудьте (‘url.intended’);
protected function unauthenticated($request, AuthenticationException $exception)
{
// dd($exception);
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'learner':
$login = 'learner.login';
break;
default:
$login = 'login';
break;
}
Session::forget('url.intented');
return redirect()->route($login);
}
Решение: очистка предполагаемого URL с помощью сеанса: забудьте (‘url.intended’);
protected function unauthenticated($request, AuthenticationException $exception)
{
// dd($exception);
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'learner':
$login = 'learner.login';
break;
default:
$login = 'login';
break;
}
Session::forget('url.intented');
return redirect()->route($login);
}
Вот пример того, что я использую в производственной среде для приложения, в котором есть два пользовательских класса, которые должны быть зарегистрированы, чтобы получить доступ к своим отдельным ресурсам. Класс User использует стандартную аутентификацию Laravel без изменений, однако пользователи моего класса Admin используют это пользовательское промежуточное ПО:
<?php
namespace App\Http\Middleware;
use App\Admin;
use Closure;
use Illuminate\Support\Facades\Auth;
class AdminMiddleware
{
public function handle($request, Closure $next)
{
if (Auth::guest()) {
return redirect(route('admin.login'));
}
if (!$request->user() instanceof Admin) {
return redirect(route('restricted'));
}
return $next($request);
}
}
Я зарегистрировал AdminMiddleware в app/Http/Kernel.php
вот так:
protected $routeMiddleware = [
'admin' => \App\Http\Middleware\AdminMiddleware::class,
/*** OTHER MIDDLEWARES ARE HERE ***/
];
в routes/web.php
файл я обернул маршруты так:
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'middleware' => 'auth:admin'], function () {
/**** ADMIN ROUTES ARE HERE ****/
});
Route::group(['middleware' => 'auth'], function () {
/**** CLIENT ROUTES ARE HERE ****/
});
И у меня есть собственный AdminLoginController, который перезаписывает $redirect
переменная пути, а также guard()
, showLoginForm()
а также redirectTo()
функционирует и выглядит так:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;
class AdminLoginController extends Controller
{
use AuthenticatesUsers;
protected $redirectTo = '/admin/home';
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function guard()
{
return Auth::guard('admin');
}
public function showLoginForm()
{
return view('auth.admin.login');
}
public function redirectTo()
{
return route('admin.home');
}
}
Наконец в config/auth.php
У меня есть следующие ссылки на охранников, провайдеров и пароли:
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Admin::class,
],
],
'passwords' => [
'admin' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 60,
],
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
Конечно, это означает, что мои администраторы и пользователи хранятся в отдельных таблицах в базе данных, но это работает очень хорошо без каких-либо проблем, поэтому я в порядке с этим.