Laravel - 具有多重身份验证的未经身份验证的重定向问题

问题描述 投票:2回答:2

我在Laravel 5.7中设置了多个身份验证系统

该网站有一个“管理员”部分和该网站的“学习者”部分。当您尝试访问任一站点的一部分时,如果您尚未登录,则会重定向您正确的登录页面。

但是,如果按照这些步骤操作,我会遇到重定向问题:

  1. 我尝试访问'admin'站点的一部分(不是登录),它将我重定向到管理员登录。
  2. 然后,如果我直接链接到“学习者”页面的登录部分并登录,而不是转到主页,它会将我重定向回管理员登录。

它正确地登录我,但不正确地重定向到其他登录页面。如果我自动重定向到'学习者'然后直接链接到管理员登录页面并登录,则问题也会发生,反之亦然。

我相信我已经将问题缩小到我在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));
    }

使用每个单独的登录页面工作正常。只是当你按照上面的过程我才能看到问题。

我在每个控制器中使用单独的中间件,如下所示:

管理员家庭控制器

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');
    }

解决方案:使用Session清除目标网址:忘记('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);
    }
php laravel authentication guard
2个回答
1
投票

解决方案:使用Session清除目标网址:忘记('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);
    }

0
投票

这是我在生产中用于具有两个用户类的应用程序的示例,这两个用户类都必须登录才能访问其各自的资源。 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);
    }
}

我在app/Http/Kernel.php中注册了AdminMiddleware,如下所示:

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,
    ],
],

当然这意味着我的管理员和用户存储在数据库中的不同表中,但它确实很好,没有任何问题,所以我完全可以接受。

© www.soinside.com 2019 - 2024. All rights reserved.