Php 如何防止Symfony中可漏洞实体的延迟加载

Php 如何防止Symfony中可漏洞实体的延迟加载,php,symfony,doctrine,Php,Symfony,Doctrine,我的问题很简单,但在谷歌搜索了一个小时后,我在网上没有找到任何线索 我试图构建一个symfonyapi,但是当返回json输出时,它会将所有关系延迟加载到输出中。虽然这不是什么大不了的事(在大多数情况下),但当它对用户信息使用这种技巧时,它真的很糟糕。因此,所有内容(密码、电子邮件等)都会显示出来 我的问题是:是否有可能在学说中将一个实体标记为受保护的实体,这样就不会使用该实体进行自动加载?在某些情况下,它非常方便,但这是一个很大的缺陷。如果无法标记实体,是否可以完全停用该实体,或在集合元素上停

我的问题很简单,但在谷歌搜索了一个小时后,我在网上没有找到任何线索

我试图构建一个symfonyapi,但是当返回json输出时,它会将所有关系延迟加载到输出中。虽然这不是什么大不了的事(在大多数情况下),但当它对用户信息使用这种技巧时,它真的很糟糕。因此,所有内容(密码、电子邮件等)都会显示出来

我的问题是:是否有可能在学说中将一个实体标记为受保护的实体,这样就不会使用该实体进行自动加载?在某些情况下,它非常方便,但这是一个很大的缺陷。如果无法标记实体,是否可以完全停用该实体,或在集合元素上停用该实体

提前谢谢

编辑:

能手和二传手都在那里

还有一个Profile类,即接口,用于所有关系。它有1对1的关系

class Profile
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\OneToOne(targetEntity="App\Entity\User", inversedBy="profile", cascade={"persist", "remove"})
     * @ORM\JoinColumn(nullable=false)
     */
    private $user;

能手和二传手都在那里

class Event
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="datetime")
     */
    private $date;


    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Profile", inversedBy="ownedEvents")
     * @ORM\JoinColumn(nullable=false)
     */
    private $profile;

    /**
     * @ORM\OneToMany(targetEntity=Post::class, mappedBy="event", orphanRemoval=true)
     */
    private $posts;

问题是,此配置文件已加载,并且用户。。。 以下是控制器的功能。但是序列化是在一个额外的方法中进行的

public function getUnreactedEvents(): JsonResponse{
        $events = $this->getDoctrine()
            ->getManager()
            ->getRepository(Event::class)
            ->getUnreactedEvents($this->profileUtils->getLoggedInProfileFromDatabase()->getId());
        return new JsonResponse($this->eventUtils->eventsToArray($events));
    }
下面是to数组函数。(有一个基类,所以有两种方法:

\Utils类:

\\Utils class:
    public function eventsToArray($events): array{
        return $this->toArray($events, array("usrEvntSts"));
    }

\\Base class:
   protected function toArray($objects, $fieldsToBeRemoved): array{
        $normalizers = [new DateTimeNormalizer(), new ObjectNormalizer()];
        $serializer = new Serializer($normalizers);

        if(!is_array($objects)){
            $objects = array($objects);
        }

        //normalizes the objects object, for circular references, returns id of the object
        //doctrine comes with own array format
        $objectsArray = $serializer->normalize($objects, 'array', [
            'circular_reference_handler' => function ($object) {
                return $object->getId();
            }
        ]);

        //some keys have to be erased from the event response
        foreach ($objectsArray as $key => $object) {
            if (method_exists($objects[0], "getProfile")){
                /** @var Profile $profile */
                $profile = $objects[$key]->getProfile();
                unset($objectsArray[$key]["profile"]);
                $objectsArray[$key]["profile"]['id'] = $profile->getId();
            }
            foreach ($fieldsToBeRemoved as $field){
                unset($objectsArray[$key][$field]);
            }
        }

        return $objectsArray;
    }
}
如您所见,我的第一个想法是删除该字段。但在我添加了一个新的实体关系(posts)后,它也有一个所有者配置文件。用户类将再次加载

输出:

    {
        "id": 1,
        "name": "xcvxycv",
        "date": "2020-06-28T18:08:55+02:00",
        "public": false,
        "posts": [
            {
                "id": 1,
                "date": "2020-06-30T00:00:00+02:00",
                "content": "sfdnsdfnslkfdnlskd",
                "profile": {
                    "id": 2,
                    "user": {
                        "id": 2,
                        "email": "alla",
                        "username": "alla",
                        "roles": [
                            "ROLE_USER"
                        ],
                        "password": "$argon2id$v=19$m=65536,t=4,p=1$a01US1dadGFLY05Lb1RkcQ$npmy0HMf19Neo/BnMqXGwkq8AZKVSCAEmDz8mVHLaQ0",
                        "salt": null,
                        "apiToken": null,
                        "profile": 2
                    },
                    "username": "sdfsdf",
                    "usrEvntSts": [],
                    "ownedEvents": [
                        {
                            "id": 3,
                            "name": "blaaaa",
                            "date": "2020-06-28T18:08:55+02:00",
                            "profile": 2,
                            "public": false,
                            "usrEvntSts": [],
                            "posts": [
                                {
                                    "id": 2,
                                    "date": "2020-06-30T00:00:00+02:00",
                                    "content": "sfdnsdfnslkfdnlskd",
                                    "profile": 2,
                                    "event": 3,
                                    "comments": []
                                }
                            ]
                        },
                        
而且它会一直持续下去……

我建议使用它。它是一个广泛使用的捆绑包,也存在于巨大的API中。您可以准确地配置哪些属性应该公开,哪些不应该公开。您还可以为公开属性构建组,并使用特定的排除策略。查看更多信息


提示:还要检查深层嵌套对象。

默认情况下,只有标记为
public
的属性被序列化,这通常会导致空序列化,因为默认情况下,所有属性都是
private
并使用(public)setters/getter来修改它们。例如,为了控制json序列化,您可以在实体上实现接口。由于您根本不提供任何代码,除了一般建议之外,我无法真正帮助您。我将编辑问题并添加代码我现在添加了代码。问题是,我不想编辑每个实体的方法…我看起来您已经有了一些编辑数组输出的功能。您还可以检查用户密钥并将其清除…是的,但我想知道,是否可以完全禁止延迟加载实体。例如禁止永远加载用户实体。这样就不会发生泄漏
    {
        "id": 1,
        "name": "xcvxycv",
        "date": "2020-06-28T18:08:55+02:00",
        "public": false,
        "posts": [
            {
                "id": 1,
                "date": "2020-06-30T00:00:00+02:00",
                "content": "sfdnsdfnslkfdnlskd",
                "profile": {
                    "id": 2,
                    "user": {
                        "id": 2,
                        "email": "alla",
                        "username": "alla",
                        "roles": [
                            "ROLE_USER"
                        ],
                        "password": "$argon2id$v=19$m=65536,t=4,p=1$a01US1dadGFLY05Lb1RkcQ$npmy0HMf19Neo/BnMqXGwkq8AZKVSCAEmDz8mVHLaQ0",
                        "salt": null,
                        "apiToken": null,
                        "profile": 2
                    },
                    "username": "sdfsdf",
                    "usrEvntSts": [],
                    "ownedEvents": [
                        {
                            "id": 3,
                            "name": "blaaaa",
                            "date": "2020-06-28T18:08:55+02:00",
                            "profile": 2,
                            "public": false,
                            "usrEvntSts": [],
                            "posts": [
                                {
                                    "id": 2,
                                    "date": "2020-06-30T00:00:00+02:00",
                                    "content": "sfdnsdfnslkfdnlskd",
                                    "profile": 2,
                                    "event": 3,
                                    "comments": []
                                }
                            ]
                        },