DoctrineEncryptBundle Symfony - зашифрованное поле обновлено, хотя сущность только выбрана - PullRequest
0 голосов
/ 07 мая 2020

На Symfony4 я использую Ambta \ DoctrineEncryptBundle для шифрования некоторых столбцов в моей БД.

Функционально, все работает нормально, но журналы показывают, что при выборе объекта, если есть грипп sh где-то тогда сущность обновляется новыми значениями в зашифрованных столбцах (простые данные не меняются, так что это просто проблема производительности: он не должен обновлять то, что не изменилось).

Вот пример функция, которая ничего не делает, кроме запроса сущности User (данные для аутентификации), которая связана с сущностью Identity (имя корпуса / имя пользователя).

    /**
    * @Route("/myaccount2/", name="myAccount2", methods={"GET", "POST"})
    * @IsGranted("ROLE_USER")
    */
    public function myAccount2(LoggerInterface $logger)
    {
        $user = $this->getUser();
        $em = $this->getDoctrine()->getManager();
        $logger->debug('before');
        $em->flush();
        $logger->debug('after');
        return $this->redirectToRoute('index');
    }

Это не должно делать ничего в БД, но журналы показывают это:

[2020-05-07 09:42:14] app.DEBUG: before [] []
[2020-05-07 09:42:14] doctrine.DEBUG: "START TRANSACTION" [] []
[2020-05-07 09:42:14] doctrine.DEBUG: UPDATE identity SET name = ?, given_name = ? WHERE id = ? ["MUIEAAYnaoFEu3KQ1Y-HH6XfRb [...]","MUIEADmhmrmQJgV-ITjZymLS-- [...]","a8c39458-8213-4534-9767-57 [...]"] []
[2020-05-07 09:42:14] doctrine.DEBUG: "COMMIT" [] []
[2020-05-07 09:42:14] app.DEBUG: after [] []

И взгляд на БД показывает, что соответствующие значения фактически обновлены.

Вот части определения задействованных сущностей:

Пользователь

    /**
    * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
    * @UniqueEntity(fields={"email"}, message="security.alreadyused")
    */
    class User implements UserInterface
    {
        /**
        * @ORM\OneToOne(targetEntity="App\Entity\Identity", mappedBy="User", cascade={"persist", "remove"})
        */
        private $identity;

Идентификация

<?php

    namespace App\Entity;

    use Ambta\DoctrineEncryptBundle\Configuration\Encrypted;
    use Symfony\Component\Validator\Constraints as Assert;
    use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
    use Doctrine\ORM\Mapping as ORM;

    /**
     * @ORM\Entity(repositoryClass="App\Repository\IdentityRepository")
     * @UniqueEntity(
     *     fields={"alias"},
     *     message="public.alias.unique"
     * ))
     */
    class Identity
    {
        /**
         * @ORM\Id()
         * @ORM\Column(type="string", length=36, nullable=false)
         */
        private $id;

        /**
         * @ORM\Column(type="string", length=1000)
         * @Encrypted
         */
        private $name;

        /**
         * @ORM\Column(type="string", length=1000)
         * @Encrypted
         */
        private $givenName;

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

Обратите внимание, что если @encrypted удаляется из двух полей (имя и имя enName) в сущности Identity, БД не обновляется:

[2020-05-07 11:06:18] app.DEBUG: before [] []
[2020-05-07 11:06:18] app.DEBUG: after [] []

Спасибо за понимание этого странного поведения!

1 Ответ

0 голосов
/ 10 июля 2020

Это поведение вызвано шифрованием. Когда doctrine загружает объект, данные расшифровываются.

Две возможности:

  • Действие дешифрования обнаруживается doctrine при изменении и планировании этого объекта выполнить обновление.

  • В действии flu sh новые зашифрованные данные не совпадают с загруженными, и данные обновляются в базе данных.

Библиотека Ambta \ DoctrineEncryptBundle должна обнаруживать изменение и изменять зашифрованное значение только в этом случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...