【问题标题】:Laravel nested resource securityLaravel 嵌套资源安全
【发布时间】:2017-04-14 08:08:53
【问题描述】:

在我目前正在进行的一个项目中,我有这样的嵌套资源

route()->resources('user', 'UserController');
route()->resources('user.place', 'PostController');
route()->resources('user.place.picture', 'PictureController');

一切正常,每次我都会传递用户的 id 等...

诀窍是当你来到一个地方时,如果这是你的,我会显示按钮来编辑和执行一些操作。所以我检查$place.user_id == $user.id 是否显示按钮。

玩了一会儿之后,因为要访问例如我的一个地方,我有以下 URL:/user/1/place/2 for the Place.show。

我是所有者,因此按钮显示并且我可以修改,但如果另一个用户(例如 user_id 2)使用相同的 URL 来查看我的位置,他无法修改任何内容,但可以查看该位置。

我发现如果该用户使用相同的 URL 但将 user_id 更改为我的,那么他可以完全访问该位置并对其进行修改。

所以为了防止这种情况,我添加了另一个条件:Auth::user()->id == $user->id

我想知道是否有解决方案来防止这种行为,因为如果我必须保护嵌套资源的每个方法,那么实现起来就会变得冗长而难看。当我进入下一个级别时user.place.picture。我想我每次下降时都需要增加另一层安全性。 $picture->place_id == $place->id 等等。

所以,当我打印一个链接以便用户可以使用正确的用户、地点、图片 ID 单击它时,没有任何东西可以阻止或检查一个 ID 是否已被修改。如果最后一个被修改,没有问题,因为它会检索另一个元素。但是,如果我们修改父母的 id 可能会很危险,尤其是当我在此过程中授予某些访问权限时。

希望有一个我错过的简单解决方案!

【问题讨论】:

标签: laravel laravel-5 model nested nested-resources


【解决方案1】:

首先,我认为你根本没有必要进行这项检查;

$place.user_id == $user.id

因为正如您所发现的,从 URL 派生的 $user 很容易被操纵,因此该保护没有任何价值。您已添加检查以确保当前登录的 UserPlace 的所有者,但这应该是您唯一的检查,您不需要两者。

如果我理解正确,这听起来像是使用 Policies in Laravel 的完美用例。该文档非常全面,但我会尝试针对您的特定用例进行总结:

  • 生成Policy,例如PlacePolicy
  • 对于您的用例,在此策略中,您将创建一个接受作为参数的update() 方法、User(登录用户)和Place(他们尝试访问的位置)李>
  • PlacePolicy 上的update() 方法现在可以通过任何方式确定User 是否可以更新Place

所以,它可能看起来像这样;

<?php

namespace App\Policies;

use App\Place;
use App\User;

class PlacePolicy
{
    /**
     * Determine if the given place can be updated by the User.
     *
     * @param  \App\User  $user
     * @param  \App\Place  $place
     * @return bool
     */
    public function update(User $user, Place $place)
    {
        return $place->user_id == $user->id;
    }
}

这是一个非常简单的检查 - 但您基本上可以在这里做任何事情来确定给定的用户是否可以对另一个模型执行操作。

注意:您需要在服务提供商中注册此政策,请参阅上面链接的文档了解如何执行此操作

有了这个Policy,你可以利用 Laravel 提供的一系列有用的工具。例如,您可以利用 Blades can 指令执行以下操作:

@can('update', $place)
    < SHOW THE EDIT BUTTON >
@endcan

您还可以通过Middleware 应用Policy 类,以防止页面被首先访问:

Route::get('/user/{user}/place/{place}' .....)->middleware('can:update,place');

希望这足以让您上路! :)

【讨论】:

    猜你喜欢
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 2021-11-05
    • 1970-01-01
    • 2016-12-30
    • 2014-12-09
    • 2019-04-30
    相关资源
    最近更新 更多