Laravel中间件,用于控制用户对数据的访问

时间:2019-02-10 10:02:52

标签: laravel laravel-5 data-access-layer laravel-middleware

我正在使用这种用户级别结构:

Company Owner
- Group Manager
-- Unit Manager
---Employee

我需要控制用户访问数据库中的数据。员工只能访问其存储的数据。单位经理也可以访问自己的数据和他的员工的数据。群组管理员可以访问整个群组的数据。公司所有者可以参加所有活动。

我有一些像这样的控制器:

class ClientController extends Controller
{
        public function index()
        {
            return Client::all();
        }
        // ...
}

在Laravel中控制某些控制器(而非所有控制器)对数据(而非控制器)的数据访问的最佳实践是什么?这里是否可以很好地解决此问题?

4 个答案:

答案 0 :(得分:2)

中间件是访问控制的正确位置。对于组中间件,您可以使用此格式

Route::group(['middleware' => ['role:Company Owner']], function() {
    Route::get('/', 'AdminController@welcome');
    Route::get('/manage', ['middleware' => ['permission:manage-admins'], 'uses' => 'AdminController@manageAdmins']);
});
Route::group(['middleware' => ['role:Employee']], function() {
    Route::get('/', 'AdminController@welcome');
    Route::get('/manage', ['middleware' => ['permission:manage-admins'], 'uses' => 'AdminController@manageAdmins']);
});

对于单条路线

Route::put('post/{id}', function ($id) {
    //
})->middleware('role:Employee');

您可以将软件包用于用户角色库访问控制

  

https://github.com/Zizaco/entrust

答案 1 :(得分:1)

您可以为每个角色创建一个中间件,然后在web.php文件中使用路由组将访问权限分配给用户可以访问的路由。因此,对于员工和部门经理都可以访问的路由,您可以通过两个中间件,对于只有组经理可以访问的路由,您只需通过组管理器即可。

Route::group(['middleware' => ['auth', 'group-manager','unit-manager']], 
function() {
  Route::get('client','ClientController@index'); 
});

答案 2 :(得分:0)

在途中。所有中间件的好地方。

Route::get('/', function () {  ...  })->middleware('web');

答案 3 :(得分:0)

也许这个问题可能还不够清楚,但是我找到了解决方案:

<?php

namespace App\Scopes;

use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

use Auth;
use App\User;

class DataAccessScope implements Scope
{
    /**
     * Apply the scope to a given Eloquent query builder.
     *
     * @param  \Illuminate\Database\Eloquent\Builder  $builder
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @return void
     */
    public function apply(Builder $builder, Model $model)
    {
        // find the actual user
        $user_id = Auth::user()->id;
        $user = User::find( $user_id );

        // get all employees
        $employees = $user->allEmployeeFlatten();

        // get only the employee's ids
        $user_ids = $employees->pluck('id');

        // add current user's id too
        $user_ids->push( $user_id );

        // add the condition to every sql query
        $builder->whereIn('user_id', $user_ids);
    }
}

这是User模型的allEmployeeFaletten()函数:

public function allEmployeeFlatten() {
    $employees = new Collection();

    foreach ( $this->employee()->get() as $employee ) {
        $employees->push( $employee );

        // run only if the user is on a leader level
        if ( $employee->user_role_id != 5 ) {
            $employees = $employees->merge( $employee->allEmployeeFlatten() );
        }
    }

    return $employees;
}

每次我使用范围时,此范围都会为所有SQL查询添加条件。