Laravel Spatie 无法限制 UserController

Posted

技术标签:

【中文标题】Laravel Spatie 无法限制 UserController【英文标题】:Laravel Spatie unable to restrict UserController 【发布时间】:2020-02-01 12:09:25 【问题描述】:

目前我有想要限制的 users.index 刀片。但是,我没有限制它。

我已经尝试创建另一个测试刀片和一个 TestController,并且我已经设置了权限并且它工作正常。

但是对于 UserController,没有办法限制用户访问它:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Spatie\Permission\Models\Role;
use Spatie\Permission\Models\Permission;
use DB;

    class TestController extends Controller
    
        /**
         * Restricting pages
         */
            public function __construct()
        
            $this -> middleware('permission:test-list', ['only' => ['index']]);
        
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        
            return view('test.index');
        

        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        
            //
        

        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        
            //
        

        /**
         * Display the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        
            //
        

        /**
         * Show the form for editing the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        
            //
        

        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        
            //
        

        /**
         * Remove the specified resource from storage.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        
            //
        
    

views/test/index.blade.php

@extends('layouts.app')
@section('content') 


<p>Testing Page</p>
@endsection

如果我不允许特定用户角色访问此页面,这些是结果。

enter image description here

enter image description here

所以以上是正确的行为。 然而,当涉及到 user.index 时,我在 UserController 的构造函数中应用了相同的技术,但它不起作用

app/Http/Controllers/UserController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\User;
use Spatie\Permission\Models\Role;
use DB;
use Hash;

class UserController extends Controller

    public function construct() 
    
        $this -> middleware('permission:user-list', ['only' => ['index']]);

    
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    
        $data = User::orderBy('id','DESC') -> paginate(5);
        return view('users.index' , compact('data')) -> with('i' , ($request->input('page', 1) - 1) * 5);
    

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    
        $roles = Role::pluck('name','name') -> all();
        return view('users.create',compact('roles'));
    

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    
        $this->validate($request, [
            'name' => 'required',
            'email' => 'required|email|unique:users,email',
            'password' => 'required|same:confirm-password',
            'roles' => 'required'
        ]);
        $input = $request -> all();
        $input['password'] = Hash::make($input['password']);
        $user = User::create($input);
        $user -> assignRole($request -> input('roles'));
        return redirect() -> route('users.index') -> with('success','User created successfully');
    

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    
        $user = User::find($id);
        return view('users.show',compact('user'));
    

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($id)
    
        $user = User::find($id);
        $roles = Role::pluck('name','name') -> all();
        $userRole = $user->roles -> pluck('name','name') -> all();
        return view('users.edit',compact('user','roles','userRole'));
    

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, $id)
    
        $this -> validate($request, [
            'name' => 'required',
            'email' => 'required|email|unique:users,email,'.$id,
            'password' => 'same:confirm-password',
            'roles' => 'required'
        ]);
        $input = $request->all();
        if( ! empty($input['password']))  
            $input['password'] = Hash::make($input['password']);
         else 
            $input = array_except($input,array('password'));    
        
        $user = User::find($id);
        $user -> update($input);
        DB::table('model_has_roles') -> where('model_id',$id) -> delete();
        $user -> assignRole($request -> input('roles'));
        return redirect() -> route('users.index') -> with('success','User updated successfully');
    

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    
        User::find($id) -> delete();
        return redirect() -> route('users.index')  -> with('success','User deleted successfully');
    

结果[尽管没有查看此页面的权限,我仍然可以在前端查看此 Blade]

enter image description here

这是我的角色权限表role-has-permission

这是我的角色表 role

这是我的权限表 permissions

这是我的模型角色表model-has-roles

这是我的模型权限表model-has-permissions

【问题讨论】:

能否请您显示“role_has_permissions”表? @sachinkumar 这是我的 roles_has_permissions 表 在哪里?我看不到。 @sachinkumar 抱歉刚刚更新了它。请重试 可以通过清除缓存、路由缓存、视图试试吗?并尝试 composer dump-autoload。 【参考方案1】:

如果你想限制特定的路线或所有你可以这样做:

Route::middleware(['auth', 'permission:user-list'])->group(function ()

Route::get('/create', 'WelcomeController@create')->name('welcome');
 ...
 ...
 ..

);

或者你可以替换

public function construct() 

    $this -> middleware('permission:user-list', ['only' => ['index']]);


public function construct() 

    $this -> middleware('permission:user-list')->except(['index']);


【讨论】:

您好,感谢您的回答,但还是不行。 嗨@EyadJaabo,我尝试使用这种方式,它突然工作 Route::middleware(['auth', 'permission:user-list'])->group(function () Route::middleware(['auth', 'permission:user-list'])->group(function () :resource('users' , 'UserController'); );非常感谢

以上是关于Laravel Spatie 无法限制 UserController的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.7 + Spatie 权限 + JWT 身份验证

我无法从 laravel 中的输入值中获取请求值

如何使用 laravel 8 +jetstream + spatie 为注册用户分配角色

Spatie / Laravel cors在生产中的问题[重复]

它是如何工作的 ?使用 Spatie/laravel-cronless-schedule 自定义的 Laravel 时间表

Spatie/Newsletter:Laravel 5.6 中提供的 MailChimp 无效 MailChimp API 密钥