【问题标题】:Laravel redirected you too many times errorLaravel 重定向你太多次错误
【发布时间】:2020-07-25 13:51:26
【问题描述】:

我正在尝试在 Laravel 7 中实现一个简单的基于角色的身份验证系统,其中我在用户表上有一个名为“角色”的整数类型的附加字段,它可以有两个值 - 0 用于一般用户,5 用于管理员。

任何登录用户都应该能够访问“/railway”页面。只有管​​理员才能访问“/admin”页面。管理员还应该能够访问“/railway”页面。

我正在关注这篇文章并收到 'too many redirect' 错误:https://dev.to/kaperskyguru/multiple-role-based-authentication-in-laravel-30pc

编辑:

抱歉忘了说!

对于非管理员用户来说,一切都运行良好。他们在正常登录后被重定向到“/railway”页面,如果他们尝试访问“/admin 页面”,也会被重定向到此页面。

该错误仅发生在管理员身上。登录后将它们重定向到“/admin”页面,但显示“重定向过多”错误。但是管理员可以访问完美的“/railway”页面。

Edit-3 如果有人有兴趣重现此问题,我已将其添加到 git 存储库中:https://github.com/rawhasan/laravel-auth-bug.git

这是我到目前为止所做的:

web.php

Route::get('/', function () {
    return view('welcome');
});

Auth::routes();

Route::get('/railway', 'RailwayController@index')->name('railway');
Route::get('/admin', 'AdminController@index')->name('admin')->middleware('admin');

中间件管理.php

namespace App\Http\Middleware;

use Auth;
use Closure;

class Admin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
      if (!Auth::check()) {
          return redirect()->route('login');
      }

      if (Auth::user()->role == 0) {
        return redirect()->route('railway');
      }

      if (Auth::user()->role == 5) {
        return redirect()->route('admin');
      }
    }
}

内核.php

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,

    'admin' => \App\Http\Middleware\Admin::class,
];

HomeController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class HomeController extends Controller
{
    public function __construct()
    {
        $this->middleware('auth');
    }

    public function index()
    {
        return view('railway');
    }
}

AdminController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AdminController extends Controller
{
    public function index()
    {
        return view('admin.admin');
    }
}

编辑 - 2

我在 LoginController.php

上也有这个
use Auth; 

class LoginController extends Controller
{
    use AuthenticatesUsers;

    protected $redirectTo;
    public function redirectTo() {
      if (Auth::user()->role = 5) {
        $this->redirectTo = '/admin';
        return $this->redirectTo;

      } else {
        $this->redirectTo = '/railway';
        return $this->redirectTo;
      }
    }

    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}

任何解决问题的帮助将不胜感激!

【问题讨论】:

  • 我看到您找到了解决方案,因此对于稍后查看此内容的任何人,您必须知道:1) 总是为您的代码创建测试,它会立即显示。 .. 2)当您使用自定义Middlewares时,请始终添加return $next($request);... 3)如果您要重定向或类似的,请检查您是否重定向到同一条路线,这很明显......如果您仍然需要它,请在询问当前 URL 是否与您要重定向的 URL 不同时写另一个...

标签: laravel


【解决方案1】:

因此,在两个用户角色中,它都需要身份验证,这意味着您可以将路由包装在默认 laravel auth 中间件下:

Route::middleware(['auth'])->group(function () {
    Route::get('/railway', 'RailwayController@index')->name('railway');
    Route::get('/admin', 'AdminController@index')->name('admin')->middleware('admin');
});

你的中间件应该是这样的:


use Auth;
use Closure;

class Admin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
      if (Auth::user()->role == 0) {
        return redirect()->route('railway');
      }

      if (Auth::user()->role == 5) {
        return redirect()->route('admin');
      }
      return $next($request);
    }
}

【讨论】:

  • 谢谢!我将第一部分放在 web.php 中,如下所示:Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::middleware(['auth'])->group(function () { Route::get('/railway', 'RailwayController@index')->name('railway'); Route::get('/admin', 'AdminController@index')->name('admin')->middleware('admin'); }); 并在管理中间件中更改了其余部分。但仍然是同样的问题。我做得对吗?
  • 请检查我对帖子的第二次编辑。忘了提到 LoginController.php 代码。
  • 您仍然拥有return redirect()->route('admin');,这意味着,在同一条路线中,它将永远重定向到同一条路线...
【解决方案2】:

在其他来源的帮助下解决了这个问题。从管理中间件中删除了以下代码,它运行良好:

if (Auth::user()->role == 5) {
    return redirect()->route('admin');
}

因为我是从 loginController 重定向管理员,所以这个来自中间件的重定向造成了冲突。

我还按照 Leo 的建议将此代码保存在 web.php 中:

Route::middleware(['auth'])->group(function () {
  Route::get('/railway', 'RailwayController@index')->name('railway');
  Route::get('/admin', 'AdminController@index')->name('admin')->middleware('admin');
});
 

感谢大家的回答!

【讨论】:

    猜你喜欢
    • 2019-02-21
    • 1970-01-01
    • 2016-10-20
    • 1970-01-01
    • 1970-01-01
    • 2018-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多