为了账号安全,请及时绑定邮箱和手机立即绑定

RESTful API 基于用户角色的不同响应

RESTful API 基于用户角色的不同响应

PHP
大话西游666 2021-09-18 10:22:17
我使用 Laravel 作为我的 PHP 框架。它是将index show store ...函数放入控制器的约定。我有两种类型的用户(管理员和普通用户)。让我们假设有一个Order(在餐厅)模型,我想index为其控制器实现功能。一个用户可以有多个订单。我需要的是这个功能:如果管理员正在调用此 API:返回所有订单如果普通用户正在调用此 API:仅返回此用户拥有的订单我搜索过,但找不到任何东西(tbh 我不知道要搜索什么)。一旦我按照以下方式执行此操作,我不喜欢它,因为它看起来两个不同的功能合二为一:if ($user->role == admin) {       // fetch all orders   } else if ($user->role == normal_user) {       // just find user orders     }所以我的问题是实现我想要的最佳方法是什么?
查看完整描述

3 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

这样的 REST API 端点通常是允许多个过滤器、排序和分页的搜索。如果是这样,完全可以为过滤器应用不同的默认值并将过滤器限制为角色。

如果没有管理员角色的用户尝试为不同的用户应用用户过滤器,我会自动应用过滤器 user=currentUser 来丢失管理员角色并返回禁止。

通过这种方法,您还可以为管理员提供搜索特定用户的报价的功能,并且您只需要一个搜索 api 即可供控制器使用。


查看完整回答
反对 回复 2021-09-18
?
BIG阳

TA贡献1859条经验 获得超6个赞

为什么不使用 if 语句?


你可以在模型上制作一个范围,但你仍然会有一个 if。


那这个呢?


if ($user->role == admin) {    

    Order::all();

} else if ($user->role == normal_user) {

   $user->orders()->get();

}

或者使它成为内联如果


$user->role == admin ? Order::all() : $user->orders()->get();


IMO 这里的最佳实践是创建一个不同的 Admin/OrderController.php


然后用中间件检查wat,用户的角色是,然后将他们重定向到admin控制器。


因为您可能还需要更新和删除,或其他只能由管理员访问的功能


查看完整回答
反对 回复 2021-09-18
?
胡说叔叔

TA贡献1804条经验 获得超8个赞

不久前我自己也有一个类似的问题,最终得到了这个奇怪的解决方案来避免 if/else 块。


假设

我假设 User 模型中存在一个辅助方法,isNot($role)用于验证用户的角色是否与给定的角色匹配。这只是给出检查想法的示例,但您应该根据需要实施条件。


我所做的第二个假设是每个订单都有一个user_id字段,该字段将通过他的 ID(用户和订单之间的 FK 1:N)引用该订单的所有者。


执行

public function index(Request $request)

{

    $orders = Order::query()

            ->when($request->user()->isNot('admin'), function ($query) use ($request) {

                return $request->user()->orders();

                // Or return $query->where('user_id', $request->user()->id);

            })

            ->paginate();


    return OrderResource::collection($orders);

}

该when方法是这里的关键。基本上你称之为:when($value, $callback)如果$value是false回调将不会被执行,否则它会。


因此,例如,如果用户不是管理员,您最终将执行此查询: Order::paginate(); 这将使用分页获取所有订单(请注意,您可以paginate与get.


否则,将执行回调并且您将执行该paginate方法$request->user()->orders();(像方法一样调用的订单仍然是查询构建器对象,因此您可以对其调用 paginate)。查询将是: $request->user()->orders()->paginate();


如果您在回调中选择了第二种解决方案,您基本上会向主范围添加一个 where 条件(过滤订单的 user_id)以仅获取用户的订单。查询将是: Order::query()->where('user_id', $request->user()->id)->paginate();


最后,为了更好地控制作为响应发回的内容,我使用了Laravel 的 API 资源(如果您需要自定义响应,我真的建议您也这样做)。


注意:代码可能有语法和/或逻辑错误,因为它只是对生产代码的即时编辑,并且还没有经过测试,但它应该给出正确实现的总体思路。


查看完整回答
反对 回复 2021-09-18
  • 3 回答
  • 0 关注
  • 126 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信