【问题标题】:Laravel 5.4: User permissions customized by sectionLaravel 5.4:按部分自定义的用户权限
【发布时间】:2018-06-27 18:47:18
【问题描述】:

我正在创建一个管理面板,您应该可以在其中分配每个用户访问和管理每个部分的权限。

users 表中,我有以下内容:

id
name
password
news
reports
events
documents
communities
videos
tags
active
created_at
updated_at

字段:新闻、报告、事件、文档、社区、视频标签,是 tinyint (1) 字段,值为“0”或“1”。如果该值等于“1”,则用户有权限;如果等于“0”,则用户没有权限。这些字段对应于面板的每个部分。

我已经成功建立了基本的访问和授权连接,但是现在我不知道如何根据用户有没有限制来检查每个部分的访问权限。我已经看到了一些权限包和用户角色,但它们并没有做我需要的事情。有什么帮助吗?

LoginController 我有:

class LoginController extends Controller
{
    protected $redirectTo = 'panel.index';

    public function username()
    {
        return 'name';
    }

    public function acceso(Request $request)
    {
        $data['name'] = $request->name;
        $password = $request->password;

        if (Auth::attempt(['name' => $data['name'], 'password' => $password, 'active' => 1])) {
            // Authentication passed...
            return view('panel.login.index', compact('data'));
        }
        else {
            return back()->with('message' , 'Ups! El nombre o la clave no son correctos.');
        }
    }

    public function index()
    {
        Auth::logout();
        return view('panel.index');
    }

}

在每个控制器中我都放了 __construct()

public function __construct()
{
    $this->middleware('auth');
}

路线我有:

// Login
    Route::resource('login', 'LoginController');
    Route::get('/panel', 'LoginController@index');
    Route::post('login/index', ['as' => 'login.acceso', 'uses' => 'LoginController@acceso']);
    Route::post('login', ['as' => 'login', 'uses' => 'LoginController@index']);

这是在视图中登录:

{!! Form::open(['method' => 'POST', 'route' => 'login.acceso', 'class' => 'form', 'id' => 'acceso_form']) !!}
    Bienvenido al Panel de Gestión.</br>
    Por favor, introduce el nombre de usuario y la clave:<br><br>

    {!! Form::text('name', '', ['class' => 'form-control', 'placeholder' => 'usuario']) !!}
    {!! Form::password('password', ['class' => 'form-control', 'placeholder' => 'clave']) !!}
    {!! Form::submit('ACCEDER', ['class' =>'btn btn-primary']) !!}

{{ csrf_field() }}
{!! Form::close() !!}
@if(session()->has('message'))
    <div class="dialogo_requerido" style="width: 80%; margin: 2em 10% 0 10%">{{ session()->get('message') }}</div>
@endif

【问题讨论】:

  • 通常你在这种情况下要做的就是在需要特定访问权限的路由周围分配一个中间件,检查通过中间件登录的用户,看看他们是否有正确的权限。如果他们不这样做,您将他们重定向到某个地方。另外,出于好奇,身份验证包没有完成什么?
  • 谢谢蒂姆,我不太清楚你说的该怎么做,我有点迷茫,我去看看能不能把它拿出来。无论如何,如果你有时间给我看一个样品,我将不胜感激。关于包,我看到的信息是指用户角色(管理员、编辑器等),但我没有看到每个用户的特定部分可以授予权限;这就是我撤消它们的原因。
  • 很公平,也可以理解。如果可以,请查看Sentinel,特别是它如何处理权限:cartalyst.com/manual/sentinel/2.0#permissions。它同时具有角色和用户权限,因此正在进行一些继承。我可以发布一个中间件如何工作的示例;给我一点时间。
  • 谢谢!我一会儿去看看。用户的这对我来说有点困难......

标签: php authentication laravel-5 login permissions


【解决方案1】:

要处理基于权限的访问,可以使用 Laravel 的中间件功能来处理。首先,让我们创建一个中间件CanAccessReportsapp\Http\Middleware\CanAccessReports.php):

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class CanAccessReports {
    public function handle($request, Closure $next, $guard = null) {

        $user = Auth::user(); // or Sentinel::getUser(), etc

        // Check if the User has access to `reports`, redirect otherwise
        if($user->reports == 0){ // or if($user->hasAccess(["reports"]){ ... }
            return back(); // or redirect("/");
        }

        return $next($request);
    }
}

接下来,通过将其添加到内核将其分配给路由:(app\Http\Kernel.php)

protected $routeMiddleware = [
    ...
    "canAccessReports" => \App\Http\Middleware\CanAccessReports::class
];

注意,您也可以将其分配给现有的中间件组,或创建自己的。取决于你想如何使用它。如果您需要更多信息,请阅读https://laravel.com/docs/5.5/middleware

最后,要在您的应用中使用它,请将其分配给一个路由/路由组:(routes\web.php):

...
// Assign to a single Route
Route::get("/reports/exampleReport", "ReportsController@example")->middleware("canAccessReports");

// Or assign to a Route Group
Route::group(["prefix" => "reports", "middleware" => "canAccessReports"], function(){
    Route::get("/exampleReport", "ReportsController@example");
});

使用这两种方法中的任何一种,如果经过身份验证的用户尝试访问http://yourApp/reports/exampleReport,但他们没有reports 的权限,他们将被重定向回来。您可以使用session()-&gt;flash("Access Denied"); 回传消息或其他方法。

我已经包含了它如何与您当前的设置一起工作(users 列中的每个权限,以及中间件中的Sentinel 函数作为示例。希望对您有所帮助!

【讨论】:

  • 哇!非常感谢你,蒂姆。我要把它集成到我的应用程序中,我会告诉你的;)
  • 亲爱的蒂姆,我有一个错误:Container.php 第 721 行中的 ReflectionException:类 canAccessReports 不存在。我要编辑我的问题,详细说明我做了什么……
  • 确认文件名在需要的地方正确,canAccessReports,小写“C”只能在Kernel.php;其他地方应该是CanAccessReports,大写。然后,如果仍然存在,请运行 composer dump-autoload 以重新加载可用的类。
  • 路线中缺少一个“s”!它工作得很好,我会完成整合它。谢谢蒂姆!
  • 是的,我已经编辑了问题并删除了该部分,以便为下一个问题保留它;)祝您有美好的一天!
猜你喜欢
  • 2015-07-29
  • 2017-07-19
  • 1970-01-01
  • 2014-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-20
  • 2010-12-24
相关资源
最近更新 更多