Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel only retrieve Model Records if they belong to authenticated user

I'm using Laravel 5.4 and have a Model called Order. To test things I've created two users and two Orders, each user having one Order.

I've just seen that I'm able to retrieve the order of someone who is not my current user. I'm retrieving a list of user's own orders using Auth::user()->orders. But in order to show the details of a specific order I do this:

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show($id)
{
    $order = CustomerOrder::findOrFail($id)->with('products')->get();
    return view('order.show')
        ->with('order', $order);
}

What am I missing out here? Is there a middleware or something to tell the application to only allow access to orders associated with the authenticated user?

Edit: So I've tried to do it using a Policy OrderPolicy (CRUD).

The view() fucntion of the Policy:

/**
 * Determine whether the user can view the customerOrder.
 *
 * @param  \App\User  $user
 * @param  \App\CustomerOrder  $customerOrder
 * @return mixed
 */
public function view(User $user, CustomerOrder $customerOrder)
{
    return $user->id === $customerOrder->user_id;
}

And I've registered it in the AuthServiceProvider.php:

protected $policies = [
    'App\Model' => 'App\Policies\ModelPolicy',
    Adress::class => AdressPolicy::class, //Doesn't work either
    Order::class => OrderPolicy::class
];

I can still check the Order for another user.

like image 922
xTheWolf Avatar asked Mar 10 '23 11:03

xTheWolf


2 Answers

You have a few options. The best option in my option is the use Policies. The documentation for this can be found here:

https://laravel.com/docs/5.4/authorization

Alternatively do could do something like:

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show($id)
{
    $user = request()->user();

    $order = $user->orders()->with('products')->find($id)->get();

    return view('order.show', compact('order'));
}

With an orders relationship function on your user model.


Updated Reply

With the policy you gave, and with your resource route, you should be able to do:

/**
 * Display the specified resource.
 *
 * @param  int  $id
 * @return \Illuminate\Http\Response
 */
public function show(CustomerOrder $order)
{
    $this->authorize('view', $order);

    return view('order.show', compact('order'));
}
like image 178
Jono20201 Avatar answered Apr 25 '23 06:04

Jono20201


Another way would be to use the defined relationship and tell it to only retrieve the one with id $id. Like this:

$customerOrder = auth()->user()->orders()->with('products')->find($id);
like image 22
DevK Avatar answered Apr 25 '23 06:04

DevK