Выйти из системы конкретного пользователя, заблокированного администратором - PullRequest
0 голосов
/ 08 января 2020

У меня есть два symfony (5) приложения, подключенных к одной и той же БД.

первое - это простая платформа для пользователей.

Второе - это интерфейс администратора.

Я хочу знать, как я могу выйти из системы пользователя после изменения значения одного из его полей в БД (статус).

Я читал о слушателях событий, но ни одно из решений не кажется чтобы исправить мои проблемы.

Есть ли способ отключить пользователя от приложения, изменив значение в БД администратором?

Спасибо

Ответы [ 2 ]

0 голосов
/ 09 января 2020

Для получения дополнительной информации: равные реализации:

public function isEqualTo(UserInterface $user): bool
    {
        if (!$user instanceof self) {
            return false;
        }

        if ($this->getPassword() !== $user->getPassword()) {
            return false;
        }

        if ($this->getSalt() !== $user->getSalt()) {
            return false;
        }

        /**Login page does not work when I add this code*/
        if ($this->getStatus() !== $user->getStatus()) {
            return false;
        }

        return true;
    }
0 голосов
/ 08 января 2020

Вы ищете isEqualTo() метод EquatableInterface.

См. https://symfony.com/doc/current/security/user_provider.html#understanding как пользователи обновляются из сеанса

Выходит из системы, если их данные, хранящиеся в сеансе, не соответствуют их данным, хранящимся в базе данных. По умолчанию он просматривает только поля password, salt и username.

Вы должны реализовать этот интерфейс в своей пользовательской сущности. Вот пример, предполагая, что сущность имеет имя User, а поле, которое должно вызвать выход из системы, называется status:

use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\UserInterface;

class User implements EquatableInterface, UserInterface
{
    // [...]

    /**

     * Compares user stored in session ($this) with his entry stored in
     * database (UserInterface $user).
     * If it returns false, user is logged out.
     *
     * @param UserInterface $user
     * @return bool
     */
    public function isEqualTo(UserInterface $user): bool
    {
        if (!$user instanceof self) {
            return false;
        }

        if ($this->getPassword() !== $user->getPassword()) {
            return false;
        }

        /*
         * Not required if you hash passwords with a self-salting algorithm like
         * Bcrypt or Argon2, which is probably the case if you didn't modify
         * default security settings.
         */
        if ($this->getSalt() !== $user->getSalt()) {
            return false;
        }

        if ($this->getUsername() !== $user->getUsername()) {
            return false;
        }

        /*
         * May not be required if your User entity and table don't use this
         * property. Plus, it's related to AdvancedUserInterface which is
         * deprecated since 4.1.
         */
        if ($this->isAccountNonExpired() !== $user->isAccountNonExpired()) {
            return false;
        }

        // Same.
        if ($this->isAccountNonLocked() !== $user->isAccountNonLocked()) {
            return false;
        }

        // Same.
        if ($this->isCredentialsNonExpired() !== $user->isCredentialsNonExpired()) {
            return false;
        }

        // Same.
        if ($this->isEnabled() !== $user->isEnabled()) {
            return false;
        }

        // This is the one you need.
        if ($this->getStatus() !== $user->getStatus()) {
            return false;
        }

        /*
         * I would recommend adding this one too. Useful e.g. to prevent user from
         * retaining access rights even if relevant role has been removed from his
         * database entry.
         * Example: user logs in while having ROLE_RESTRICTED in his database
         * entry, then an admin removes this role.
         * Without this check the application still considers the user has
         * ROLE_RESTRICTED on this session.
         *
         * Tested with the IsGranted security feature and the access_control
         * feature from the firewall.
         * Both appear to check the (potentially outdated) user object in session,
         * not the up-to-date user object in database.
         */
        if ($this->getRoles() !== $user->getRoles()) {
            return false;
        }

        return true;
    }

    // [...]
}

Обратите внимание, что при реализации isEqualTo() необходимо переписать весь метод как проверка по умолчанию (см. ресурс, который я связал) больше не будет работать для этого объекта пользователя. Это может быть проблемой безопасности, особенно если вы не отметите поле password, поскольку злоумышленник не выйдет из системы, даже если законный пользователь изменит пароль своей учетной записи.

Кроме того, обратите внимание, что это Метод, похоже, не выходит из системы пользователя, если он только что изменил данные во время того же сеанса, например, через форму редактирования пароля / имени пользователя. Это может быть связано с тем, как обрабатываются сеансы, и с методом ORM flush().

Что касается альтернативного решения с использованием прослушивателей событий, я думаю, вы могли бы проверить состояние пользователя в прослушивателе запросов ядра и при необходимости перенаправьте его на маршрут выхода из системы.

...