如何向 laravel Milldeware 中具有特定角色的用户验证特定路由

How to authenticate specific route to user with specific role in laravel Milldeware

我有多个拥有多个权限的用户。一个用户可以属于唯一的一个角色,但该角色可以拥有多个权限,如 createreadupdatedelete。我有一个RoleMiddleware。我正在验证 roleMiddleware 中的用户。但是我如何保护 RoleMiddleware 中的 routes 免受特定用户的侵害?

例如,我有一个路由 create-case 只能由 operatorAdmin 访问,否则每个人都会重定向到 404 error 我该如何处理它在 RoleMiddleware.

我已经编写了用于身份验证的基本代码,其中每个具有其角色的用户都经过身份验证,但我正在了解如何在中间件中进行编码,以便在用户点击它时路由到 RoleMiddleware 其中中间件 Authenticate路由到角色,然后给他访问权限。

角色中间件

class RoleMiddleware
{
    public function handle($request, Closure $next, $permission = null)
    {

        if (Auth::check() === false)
        {
            return redirect('login');
        }
        elseif (Auth::check() === true)
        {
            $roles = Role::all()->pluck('slug');

            if (is_null($request->user()) )
            {
                abort(404);
            }
            if (!$request->user()->hasRole($roles))
            {
                abort(404);
            }

            if ($request->user())
            {
                if ($request->user()->hasRole($roles))
                {
                    return $next($request);
                }
            }
        }
    }
}

案件负责人:

<?php

namespace App\Http\Controllers\Cases;

use App\Http\Controllers\Controller;
use App\Http\Requests\CaseStoreRequest;
use Illuminate\Support\Facades\Auth;
use Session;

class CaseController extends Controller
{
    use DropzoneFileUploadTraits;

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

    }

    public function index()
    {
        $data['portal'] = Portal::all();
        $data['operators'] = Operator::all();

        return view('case', $data);
    }

    public function caseList()
    {
        $user = new User();
        $isAdmin = $user->isAdmin();

        $loggedIn = Auth::id();

        $cases = Cases::with('patients', 'portal')
            ->when(!$isAdmin, function ($query) use ($loggedIn) {
                return $query->where('user_id', $loggedIn);
            })->orderBy('created_at', 'desc')->get();

        $data['cases'] = $cases;

        return view('case_list', $data);
    }
}

路线:

Route::get('create-case', 'Cases\CaseController@index')->name('create-case');
Route::post('case-submit', 'Cases\CaseController@caseSubmit')->name('case-submit');
Route::post('edit-patient-case-submit', 'Cases\CaseController@editPatientCaseSubmit')->name('edit-patient-case-submit');
Route::get('case-list', 'Cases\CaseController@caseList')->name('case-list');

以干净的方式做到这一点的最佳方法是针对目标实体创建策略。 Laravel 政策允许您:

  • 将路由授权逻辑绑定到策略操作

  • 从项目中的任何其他地方(视图、控制器等)轻松调用策略操作结果。

这个主题在 Laravel 文档中有很好的介绍,所以我建议你去那里看看。不要忘记注册策略并将其绑定到您的模型。

除此之外,这应该可以解决问题。

class CasePolicy
{
    use HandlesAuthorization;

    public function create(User $user){
        $roles = ['operator','Admin']
        return $user->hasRole($roles);
    }
}

然后在你的路由文件中:

Route::get('create-case', 'Cases\CaseController@index')->name('create-case')->middleware('can:create,App\Case');

我刚刚学习并实施了 Gate 和 Policy 希望这是正确的因为它对我有用。很棒的概念谢谢。

Route::get('create-case', 'Cases\CaseController@index')->name('create-case')->middleware('can:create-case,App\Model\Case');

门:

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        // 'App\Model' => 'App\Policies\ModelPolicy',

        User::class => CreateCase::class

    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();

        Gate::define('create-case','App\Policies\CreateCase@create_case');

    }
}

政策

class CreateCase
{
    use HandlesAuthorization;

    /**
     * Create a new policy instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    public function create_case(User $user){

        if($user->hasRole(['admin']) ||$user->hasRole(['operator']) && $user->hasPermissionTo('create')){

            return true;
        }else
            return false;

    }
}