【问题标题】:Restrict route access to non-admin users限制非管理员用户的路由访问
【发布时间】:2015-08-19 01:30:39
【问题描述】:

目标

我正在尝试为我的登录用户创建管理路由限制。 我尝试检查我的用户是否为log-in,以及用户类型是否为Admin,如果是,我想允许他们访问管理路由,否则,响应 404。


routes.php

<!-- Route group -->
$router->group(['middleware' => 'auth'], function() {

    
    <!-- No Restriction -->
    Route::get('dashboard','WelcomeController@index');
   
    <!-- Admin Only -->
    if(Auth::check()){
        if ( Auth::user()->type == "Admin" ){

            //Report
            Route::get('report','ReportController@index');
            Route::get('report/create', array('as'=>'report.create', 'uses'=>'ReportController@create'));
            Route::post('report/store','ReportController@store');
            Route::get('report/{id}', array('before' =>'profile', 'uses'=>'ReportController@show'));
            Route::get('report/{id}/edit', 'ReportController@edit');
            Route::put('report/{id}/update', array('as'=>'report.update', 'uses'=>'ReportController@update'));
            Route::delete('report/{id}/destroy',array('as'=>'report.destroy', 'uses'=>'ReportController@destroy'));

        }
    }

});

结果

它没有按我的预期工作。它会引发 404 错误 - 即使对于管理员用户也是如此。

【问题讨论】:

  • 你在缓存你的路由吗?

标签: php laravel laravel-5 laravel-routing laravel-middleware


【解决方案1】:

对于这个简单的案例,您可以使用Middleware

  1. 创建中间件:
php artisan make:middleware AdminMiddleware
namespace App\Http\Middleware;

use App\Article;
use Closure;
use Illuminate\Contracts\Auth\Guard;

class AdminMiddleware
{
    /**
     * The Guard implementation.
     *
     * @var Guard
     */
    protected $auth;

    /**
     * Create a new filter instance.
     *
     * @param  Guard  $auth
     * @return void
     */
    public function __construct(Guard $auth)
    {
        $this->auth = $auth;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($this->auth->getUser()->type !== "admin") {
            abort(403, 'Unauthorized action.');
        }

        return $next($request);
    }
}
  1. 添加到app\Http\Kernel.php:
protected $routeMiddleware = [
    'admin' => 'App\Http\Middleware\AdminMiddleware',
];
  1. 在路由中使用中间件:
Route::group(['middleware' => ['auth', 'admin']], function() {
    // your routes
});

【讨论】:

  • 我必须说这很快!和完美的答案
  • 另外一种更“干净”的方法是将中间件放在控制器的构造函数中。但这取决于你
  • 如果你把中间件放在你的控制器中,你会遇到传递给中间件构造函数的 Guard 的问题,因为 $auth 有一个空的用户属性,即使你已经登录了。\Auth:: user() 在创建的中间件的构造函数和句柄方法中也是 null。这迫使我必须在路由调用的每个方法中检查用户的访问权限,而不是在控制器的构造函数中。路由缓存问题在 99% 的情况下都可以解决,但为了真正安全,我认为需要在每个方法内部进行检查。有点痛苦,如果有人知道更好的方法,请告诉我
  • 我不得不提到 在你的控制器中启用中间件,使用中间件的键,而不是类名:$this->middleware('admin'); 这里缺少步骤。谢谢
【解决方案2】:

这个答案是关于为什么您的代码不能按预期工作。 @limonte 的解决方案是正确的,是我能想到的最好的。

解析您的路线文件以获取您的路线,然后,这些路线可能会缓存在其他地方。

因此,您不应放置任何依赖于请求的代码(例如检查用户是否有足够的权限来访问路由)。

特别是,您不应在您的 routes.php 中使用以下依赖于请求的模块(并非详尽无遗):

  • Auth
  • DB 或任何可能依赖于时间的数据库查询
  • Session
  • Request

您应该将您的 routes.php 作为配置的一部分查看,只是碰巧它是直接用 php 编写的,而不是您必须学习的一些新语言。

【讨论】:

    猜你喜欢
    • 2020-07-21
    • 2018-04-27
    • 2022-09-23
    • 2022-11-05
    • 2019-08-11
    • 2017-06-28
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    相关资源
    最近更新 更多