Symfony 2 security: активация аккаунта

Я использую систему безопасности Symfony 2.

когда какой-то пользователь пытается войти в систему, я хочу дополнительно проверить, является ли поле пользователя "активировано" истинным. Если нет, появится сообщение об ошибке:"сначала вы должны активировать свою учетную запись".

Как я могу реализовать эту функцию?

3 ответов


Если вы используете доктрина как поставщик пользователей можно использовать тег AdvancedUserInterface. Этот интерфейс (определение видно ниже) предоставляет isEnabled() метод, который равен методу статуса активации учетной записи. Если этот метод возвращает false, то пользователь получит сообщение об ошибке, как ваша учетная запись не активирована когда он пытается войти.

Я использую его для обеспечения проверки электронной почты по подписке.

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Security\Core\User;

/**
 * AdvancedUserInterface adds status flags to a regular account.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface AdvancedUserInterface extends UserInterface
{
    /**
     * Checks whether the user's account has expired.
     *
     * @return Boolean true if the user's account is non expired, false otherwise
     */
    function isAccountNonExpired();

    /**
     * Checks whether the user is locked.
     *
     * @return Boolean true if the user is not locked, false otherwise
     */
    function isAccountNonLocked();

    /**
     * Checks whether the user's credentials (password) has expired.
     *
     * @return Boolean true if the user's credentials are non expired, false otherwise
     */
    function isCredentialsNonExpired();

    /**
     * Checks whether the user is enabled.
     *
     * @return Boolean true if the user is enabled, false otherwise
     */
    function isEnabled();
}

я попробовал в первый раз. но получил сообщение об ошибке "Пользователь заблокирован" он пытается выяснить, как реализовать form AdvanceUserInterface.

Я хочу поделиться кодом, как это реализовать, вот так :

class User implements AdvancedUserInterface, \Serializable
{
/**
 * @ORM\Column(type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @ORM\Column(type="string", length=25, unique=true)
 */
private $username;

/**
 * @ORM\Column(type="string", length=255)
 * @Assert\Length(min=8, max=255)
 */
private $password;

/**
 * @ORM\Column(type="string", length=60, unique=true)
 * @Assert\Email(message = "The email '{{ value }}' is not a valid email.", checkMX = true, checkHost = true)
 */
private $email;

/**
 * @ORM\Column(name="is_active", type="boolean")
 */
private $isActive;

/**
 * @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
 *
 */
private $roles;

private $salt;


public function __construct()
{
    $this->isActive = true;
    $this->roles = new ArrayCollection();
    // may not be needed, see section on salt below
    // $this->salt = md5(uniqid(null, true));
}

/**
 * @inheritDoc
 */
public function getUsername()
{
    return $this->username;
}

/**
 * @inheritDoc
 */
public function getSalt()
{
    // you *may* need a real salt depending on your encoder
    // see section on salt below
    return null;
}

/**
 * @inheritDoc
 */
public function getPassword()
{
    return $this->password;
}

/**
 * @inheritDoc
 */
public function getRoles()
{
    //return array('ROLE_USER');
    return $this->roles->toArray();
}

/**
 * @inheritDoc
 */
public function eraseCredentials()
{
}

/**
 * @see \Serializable::serialize()
 */
public function serialize()
{
    return serialize(array(
        $this->id,
        $this->username,
        $this->password,
        // see section on salt below
        // $this->salt,
    ));
}

/**
 * @see \Serializable::unserialize()
 */
public function unserialize($serialized)
{
    list (
        $this->id,
        $this->username,
        $this->password,
        // see section on salt below
        // $this->salt
    ) = unserialize($serialized);
}


/**
 * Get id
 *
 * @return integer 
 */
public function getId()
{
    return $this->id;
}

/**
 * Set username
 *
 * @param string $username
 * @return User
 */
public function setUsername($username)
{
    $this->username = $username;

    return $this;
}

/**
 * Set password
 *
 * @param string $password
 * @return User
 */
public function setPassword($password)
{
    $this->password = $password;

    return $this;
}

/**
 * Set salt
 *
 * @param string $salt
 * @return User
 */
public function setSalt($salt)
{
    $this->salt = $salt;

    return $this;
}    

/**
 * Set email
 *
 * @param string $email
 * @return User
 */
public function setEmail($email)
{
    $this->email = $email;

    return $this;
}

/**
 * Get email
 *
 * @return string 
 */
public function getEmail()
{
    return $this->email;
}

/**
 * Set isActive
 *
 * @param boolean $isActive
 * @return User
 */
public function setIsActive($isActive)
{
    $this->isActive = $isActive;

    return $this;
}

/**
 * Get isActive
 *
 * @return boolean 
 */
public function getIsActive()
{
    return $this->isActive;
}

/**
 * Add roles
 *
 * @param \Bsi\BkpmBundle\Entity\Role $roles
 * @return User
 */
public function addRole(\Bsi\BkpmBundle\Entity\Role $roles)
{
    $this->roles[] = $roles;

    return $this;
}

/**
 * Remove roles
 *
 * @param \Bsi\BkpmBundle\Entity\Role $roles
 */
public function removeRole(\Bsi\BkpmBundle\Entity\Role $roles)
{
    $this->roles->removeElement($roles);
}

public function isEnabled() 
{        
    return $this->getIsActive();
}
public function isAccountNonExpired() 
{        
    return true;
}
public function isAccountNonLocked() 
{        
    return true;
}
public function isCredentialsNonExpired() 
{        
    return true;
}
}

вы можете использовать ту же процедуру, описанную для работы с просроченными паролями:

как использовать свойство credentials expired в Symfony AdvancedUserInterface?

кроме вас будет управлять заблокирована исключение:

http://api.symfony.com/2.5/Symfony/Component/Security/Core/Exception/LockedException.html


игнорировать этот раздел. Он не применяется при использовании кода безопасности symfony

просто следуйте http://symfony.com/doc/current/cookbook/service_container/event_listener.html и обрабатывать различные исключения безопасности там:


при использовании кода безопасности symfony

вы не можете послушать ядра.события исключения при работе с формой login. Код безопасности обрабатывает все исключения внутренне.

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

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


обработчики успеха/сбоя аутентификации не могут использоваться для перенаправления на изменить форму пароля, так как пользователь все готов отказано, когда они выполняются.

хотя они оказались отличными местами для отправки событий, таких как "account_disabled", "account_locked", "account_expired" или "credentials_expired".

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

пользовательский прослушиватель аутентификации будет для этого вполне может понадобиться. Другая возможность - реализовать доктрину onload listener и auth voter, которая устанавливает флаг "временного пользователя", когда срок действия учетной записи/учетных данных истек, и разрешает доступ к изменению атрибутов пользователя.

Мне в конечном итоге нужно будет реализовать какое-то аналогичное решение, но в настоящее время у меня нет времени.

вероятно, есть и другие способы.