我有一个“安全”服务,我想逐渐移至Laravel Gate,因此我可以从Laravel在APP其余部分中提供的帮助方法中受益。
我现在对门的定义如下:
Gate::define('denja', function($user, $module, $permission) {
// validation of access to $module and $permission goes here
});
这在我做的时候很好
$user->can('denja', ['accounting', 'invoice.create']);```
例如,但我看不到如何定义中间件以使其正常运行...
Route::post( '/accounting/invoices', 'InvoiceController@create')
->middleware("can:denja,accounting,invoice.create");```
从中间件传递这些参数似乎是不可能的-页面现在总是返回403
...
关于如何将这些参数正确地从中间件传递给Gate的任何想法?我认为这实际上是参数的问题;即使在定义的门中有dd()
,我也得到了403
。
我知道我有点“滥用”系统,但是由于我们现有的服务基本上希望该模块下的用户,模块和权限,所以我现在只想委托给该服务... < / p>
答案 0 :(得分:1)
使用can
中间件时:
第一个是我们希望授权的操作的名称,第二个是我们希望传递给策略方法或Model类路径的route参数。 documentation
例如:
Route::put('/post/{postId}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,postId');
OR
Route::post('/post', function () {
// The current user may create posts...
})->middleware('can:create,App\Post');
在您的情况下:
Route::post( '/accounting/invoices', 'InvoiceController@create')
->middleware("can:denja,accounting,invoice.create");
缺少基本参数签名,因为没有名称为accounting
或invoice.create
的路由参数,也没有类。
解决方案:
从路由声明中删除中间件:
Route::post( '/accounting/invoices', 'InvoiceController@create');
您可以在控制器中使用can()
方法:
public function create(Request $request){
// Initialize $model and $permissions
// as per your business logic
if(!$request->user()->can('denja', $module, $permission){
abort(403);
}
// continue your logic for authorised user
}
即使以上解决方案可行,但如果您有更多的授权规则,最好创建一个policy类。
答案 1 :(得分:1)
我遇到了同样的问题,所以我做了一些“ can”中间件的研究(哪个映射到Illuminate\Auth\Middleware\Authorize
)
在课堂上,我们将看到以下代码
/**
* Get the model to authorize.
*
* @param \Illuminate\Http\Request $request
* @param string $model
* @return \Illuminate\Database\Eloquent\Model|string
*/
protected function getModel($request, $model)
{
if ($this->isClassName($model)) {
return trim($model);
} else {
return $request->route($model, null) ?:
((preg_match("/^['\"](.*)['\"]$/", trim($model), $matches)) ? $matches[1] : null);
}
}
这意味着...
如果传入的字符串是一个类名,则返回该类名
如果不是类名,则...
1)尝试从路线获取它,然后返回路线参数
2)尝试通过正则表达式"/^['\"](.*)['\"]$/"
从字符串中获取模型
现在让我们说我们有一个中间件调用
$this->middleware(sprintf("can:create,%s,%s", User::class, Role::SUPPORT));
由于Role::SUPPORT
与正则表达式不匹配,因此无法使用
要匹配它,我们只需要将Role::SUPPORT
放在引号中即可。
注意第二个%s附近的“'”
$this->middleware(sprintf("can:create,%s,'%s'", User::class, Role::SUPPORT));
要具体回答您的问题,请引用您的字符串
Route::post('/accounting/invoices', 'InvoiceController@create')
->middleware("can:'denja','accounting','invoice.create'");