如何将多个字符串变量传递给Laravel门
我有一个“安全”服务,我想逐渐转移到Laravel Gate,这样我就可以从Laravel在应用程序的其余部分提供的助手方法中获益 我现在对大门的定义如下:如何将多个字符串变量传递给Laravel门,laravel,Laravel,我有一个“安全”服务,我想逐渐转移到Laravel Gate,这样我就可以从Laravel在应用程序的其余部分提供的助手方法中获益 我现在对大门的定义如下: Gate::define('denja', function($user, $module, $permission) { // validation of access to $module and $permission goes here }); 当我这样做的时候,这个很好用 $user->can('denja', [
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,您有什么想法吗?我认为这实际上是一个参数问题;即使定义的gate中有一个dd()
,我也会得到403
我知道我有点“滥用”系统,但由于我们现有的服务基本上需要用户、模块和该模块下的权限,我现在只想委托给该服务…当您使用
can
中间件时:
第一个是我们希望授权的操作的名称,第二个是我们希望传递给策略方法或模型类路径的路由参数
例如:
Route::put('/post/{postId}', function (Post $post) {
// The current user may update the post...
})->middleware('can:update,postId');
或
就你而言:
Route::post( '/accounting/invoices', 'InvoiceController@create')
->middleware("can:denja,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
}
即使上述解决方案有效,如果您有更多的授权规则,最好创建一个类。我也遇到了同样的问题,因此我深入研究了“can”中间件(它映射到illumb\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) 尝试从route获取它,然后返回route参数
2) 尝试通过regex“/^['\'”](.*)['\']$/”
现在让我们假设中间件调用
$this->中间件(sprintf(“can:create,%s,%s”,User::class,Role::SUPPORT))代码>
这将不起作用,因为Role::SUPPORT
与正则表达式不匹配
为了匹配它,我们只需要将Role::SUPPORT
放在引号中。
注意第二个%s周围的“'”
$this->中间件(sprintf(“can:create,%s,'%s',User::class,Role::SUPPORT”)代码>
要具体回答您的问题,请引用您的字符串
Route::post('/accounting/invoices', 'InvoiceController@create')
->middleware("can:'denja','accounting','invoice.create'");
嗯,谢谢你的回复。实际上,我正在寻找一种最简单的方法,可以定义一个“通配符”门,它可以透明地检查SecurityService的权限。我更喜欢在mu路由中,而不是在每个控制器中。。。我现在有了自己的中间件,但我有兴趣将其转移到Laravel gate系统。看来盖茨不允许我这么做。。。
Route::post('/accounting/invoices', 'InvoiceController@create')
->middleware("can:'denja','accounting','invoice.create'");