首页 > 解决方案 > How is Model::find($id) secure in Laravel?

问题描述

I have an app where I create entries based on who is signed in. If I use the find($id) method it returns json response. The function is like this:

public function edit($id)
    {
        $chore = Chore::find($id);
        return response()->json($chore);
    }

Now if I where to edit the id value I might be able to access other user's data which isn't secure at all. So I added and extra column user_id that checks who is signed in:

public function edit($id)
    {
        $chore = Chore::find($id)
        ->where('user_id', Auth::id());
        return response()->json($chore);
    }

But of course laravel can't make it easy so it doesn't work. Adding ->get() returns an array instead of a json response. First of all how is find($id) ever secure in any app that uses authentication and secondly how do I add another condition under the find($id) clause? I need data returned in JSON otherwise I will need to rewrite all my front-end which isn't ideal at this point.

I also tried:

 public function edit($id)
    {
        $chore = Chore::where('id', $id)
        ->where('user_id', Auth::id());
        return response()->json($chore);
    }

but no luck

标签: phplaravel

解决方案


如果 Chore 与您的 User 模型是一对一的关系,那么您可以在您的User.php模型中创建关系。

public function chore() {
    return $this->hasOne(Chore::class);
}

然后在您的控制器中,您可以简单地调用auth()->user()->chore.

Eloquent 的find()方法仅通过主键查找一条记录。如果您使用额外的验证,它是非常安全的。您可以使用路由模型绑定来简化代码。

网页.php

Route::get('/chore/{chore}/', 'ChoreController@edit');

然后在你的控制器中

public function edit(Chore $chore)
{
   if (! $chore->user_id === auth()->id()) {
     // throw error or redirect, or whetever
   }

   return response()->json($chore);
}    

为了进一步简化控制器,您可以创建一个表单请求并将其作为常规请求注入到控制器的方法中。(https://laravel.com/docs/7.x/validation#authorizing-form-requests

然后您可以将验证移动到您的表单请求中。它应该看起来像这样:

    public function authorize() {
        return $this->route('chore')->user_id === $this->user()->id
    }

推荐阅读