我正在使用这种用户级别结构:
Company Owner
- Group Manager
-- Unit Manager
---Employee
我需要控制用户访问数据库中的数据。员工只能访问其存储的数据。单位经理也可以访问自己的数据和他的员工的数据。群组管理员可以访问整个群组的数据。公司所有者可以参加所有活动。
我有一些像这样的控制器:
class ClientController extends Controller
{
public function index()
{
return Client::all();
}
// ...
}
在Laravel中控制某些控制器(而非所有控制器)对数据(而非控制器)的数据访问的最佳实践是什么?这里是否可以很好地解决此问题?
答案 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');
您可以将软件包用于用户角色库访问控制
答案 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查询添加条件。