中间件中怎么获取参数 id

我想写一个中间件拦截用户访问的数据id,根据这个id判断是否属于该用户的数据。
比如用户访问 xxx.yuming.com/articles/123 查看文章详情
在 public function show($id) 方法里可以直接获取到id,也可以通过 request()->route(‘article’) 获取到id,但是从中间件中不可以直接接收 $id 参数,也不能用request()->route(‘article’)这种方式获取,因为中间件是共用的,‘article’参数不固定
不知道有没有大神能不能提供一个好的方法能够准确的获取到 id

《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

你目前提出的想法不好,而且实现不了,你的想法是一个中间件,去验证所有数据表的数据,想法有问题,如果你是要做路由限制,RBAC、Auth都可以实现,如果是数据限制,如:某个表的数据你想让有权限的人【数据创建者、超级管理员等】才能修改, 你要么就在控制器内写if,或者封装成方法、函数,这里肯定推荐你使用policy策略进行控制。policy策略

3年前 评论
xujinhuan (楼主) 3年前
Siam (作者) 3年前
讨论数量: 9

@lidongYo 这里我看到了,但是没怎么明白,感觉不适用我这个场景

3年前 评论

file

Route::get('articles/{id}','ArticlesController@show')->middleware('article')->name('Articles.show');

特意去试了一下,我这样是能获取到id的

3年前 评论

@lidongYo 你把参数字段名定义为id了,当然可以通过‘id’来获取,我的项目里很多都是资源路由,比如文章的 需要通过request()->route('article') 获取 ,这是你事先知道 id 的字段名是 ‘id 或者 ‘article’’,如果通过一个中间件,获取所有用户访问的资源,就不是 id或者article了,不知道你有没有看明白

3年前 评论
super_duan 3年前

你这种可以使用权限管理扩展包,spatie/laravel-permission

Route::group(['middleware' => ['permission:publish articles|edit articles']], function () {
    //
});

自己写的中间件也可以参考这种写法,把不同资源对应的id字段名传替给中间件就行了,然后这样获取中间件参数

public function handle($request, Closure $next, $permission)
    {
        if (app('auth')->guest()) {
            throw UnauthorizedException::notLoggedIn();
        }

        $permissions = is_array($permission)
            ? $permission
            : explode('|', $permission);

        foreach ($permissions as $permission) {
            if (app('auth')->user()->can($permission)) {
                return $next($request);
            }
        }

        throw UnauthorizedException::forPermissions($permissions);
    }
}
3年前 评论
$request->route()->parameters
...
3年前 评论

@大毛 这种方法我知道,这是获取的所有的参数,你有好的办法准确的获取id的值吗,我现在也是用的这种方法,我看文档里说的往控制器里传id也是根据参数的顺序依次注入到控制器里,所以我就获取的第一个参数作为id值了

3年前 评论
大毛 3年前
xujinhuan (作者) (楼主) 3年前

@Klightsaber 这种也是个办法,不过还是没有解放双手啊 :joy: 这需要手动把所有的资源id名称都告诉他才行 :smiley: 如果是这样的话,我倒不如在每个控制器里都写一个中间件,省的引入新的扩展包

3年前 评论

你目前提出的想法不好,而且实现不了,你的想法是一个中间件,去验证所有数据表的数据,想法有问题,如果你是要做路由限制,RBAC、Auth都可以实现,如果是数据限制,如:某个表的数据你想让有权限的人【数据创建者、超级管理员等】才能修改, 你要么就在控制器内写if,或者封装成方法、函数,这里肯定推荐你使用policy策略进行控制。policy策略

3年前 评论
xujinhuan (楼主) 3年前
Siam (作者) 3年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!