什么是正确的方式'授权此REST API请求?

时间:2015-11-16 23:50:23

标签: php api rest laravel

我正在建立一个REST Api,我坐在这里遇到了问题。我决不是这方面的专家,所以我想学习如何以正确的方式解决REST架构问题。 (或者至少以某种有意义的方式)。

我正在使用Angular Frontend和基于laravel的RESTfull后端API构建Web应用程序。该应用程序有这3个表:专辑,帖子和评论。如果用户是该专辑的成员,则用户可以在专辑中写帖子。

可以邀请用户成为相册的成员,然后查看其所有帖子以及这些帖子的评论。如果用户不是(被邀请成为)相册的成员,则无法对该相册中的帖子发表评论。

换句话说:如果用户对帖子发表评论,则帖子必须来自用户所属的相册。

我的困境是:如何检查/授权此请求?

我雄辩的关系如下:

  • 用户表与相册有多对多的关系
  • 相册有很多帖子
  • 帖子有很多评论

传入请求是一个POST请求,有2个参数:

  • album_id(帖子所在的专辑)
  • post_id(对于正在评论的帖子)
  • body(实际评论本身)

通过Auth :: user()检索帖子的作者;

我对解决这个问题的初步想法是:

  1. 我检查用户是
  2. 成员的所有相册
  3. 构建一个包含用户所属相册的ID的数组
  4. 检查post_id参数是否在该数组中
  5. 如果不是,则用户无法发表评论,如果是,用户可以发表评论
  6. 到目前为止我的代码:

    // Validate the Request Body
    $input = $this->request->only([ 'album_id', 'post_id', 'comment' ]);
    
    $validator = Validator::make( $input, [
    
        'album_id'  => 'required|integer',
        'post_id'   => 'required|integer',
        'comment'   => 'required',
    
    ]);
    
    // Authorize the Request
    $albumIdList = Auth::user()->albums()->get()->pluck('id')->toArray();
    
    $postIdList = Post::whereIn( 'album_id', $albumIdList )->select('id')->get()->toArray();
    
    if( ! in_array($this->request->get('post_id'), $albumIdList))
        return abort(403);
    
    // Store the new comment
    $comment = Comment::create([
    
        'user_id'   => Auth::user()->id,
        'post_id'   => $input['post_id'],
        'comment'   => $input['comment'],
    
    ]);
    
    return $comment;
    

    我认为这是正常的,但如果一张专辑有1000个帖子怎么办?构建所有帖子ID的数组对于服务器而言变得非常密集......专业公司(如Facebook,Twitter,Pinterest)如何在他们的Web应用程序中解决这个问题?

    提前致谢!

1 个答案:

答案 0 :(得分:2)

您正在寻找whereHasexists方法:

$allowed = Auth::user()->albums()->whereHas('post', function ($query) {
    $query->where($this->request->only('post_id'));
})->exists();

此外,没有理由传递album_id。您的代码可以简化为:

$this->validate($this->request, [
    'post_id' => 'required|integer',
    'comment' => 'required',
]);

$allowed = Auth::user()->albums()->whereHas('posts', function ($query) {
    $query->where($this->request->only('post_id'));
})->exists();

if (! $allowed) return abort(403);

$input = $this->request->only('post_id', 'comment');

return Comment::create($input + ['user_id' => Auth::id()]);

如果你想进一步清理它,你应该查看Laravel的authorization facilities