2

HybridAuth 2 ライブラリ用に独自の Symfony 2 認証プロバイダーを作成しました。認証プロセスは正常に機能しますが、ユーザーが正常に認証された後、ページが更新され、ユーザー プロバイダーで refreshUser() が呼び出されると getId() メソッドが返されます。 0 (ゼロ)。refreshUser() メソッドの先頭に var_dump($user) を配置すると、id パラメータが 1 (ゼロではない!!) に設定された認証済みユーザー オブジェクトが表示されますが、getId() メソッドは引き続きゼロを返します。私の ORM エンティティ オブジェクトでは、ユーザーの getId メソッドが $this->id を返します。

他のプロバイダーを使用すると問題なく動作しますが、このプロバイダーでのみユーザー ID がゼロになります。

認証プロバイダーで var_dump($user->getId()) を試行すると、トークンが返される直前に、ユーザー ID が 1 と表示されます。

何が間違っているのかわかりません...

@edit: コードは次のとおりです。

データベースから (「user_provider」タブから) ユーザーをロードするユーザー プロバイダー。ユーザーと OneToOne の関係があり、getUser() メソッドでユーザー オブジェクトを返します。

/**
 * {@inheritdoc}
 */
public function loadUserByHybridAuthUserResponse($providerId, $providedId)
{
    $userProvider = $this->userProviderManager->findOneByProvidedId($providerId, $providedId);

    if (null === $userProvider) {
        throw new AccountNotLinkedException(
            sprintf('Your %s account is not linked to any account.', ucfirst($providerId))
        );
    }

    $user = $userProvider->getUser();

    return $user;
}

認証プロバイダー:

/**
 * {@inheritDoc}
 */
public function authenticate(TokenInterface $token)
{
    if (! $this->supports($token)) {
        return null;
    }


    $provider = $token->getProviderAdapter();
    $userId   = $token->getUser();


    try {
        $user = $this->userProvider->loadUserByHybridAuthUserResponse($provider, $userId);
    } catch (AccountNotLinkedException $e) {
        $e->setProviderAdapter($token->getProviderAdapter());
        throw $e;
    }


    // Try to authenticate user
    $authenticatedToken = new HybridAuthToken($provider, $user, $user->getRoles());

    $this->userChecker->checkPostAuth($user);

    return $authenticatedToken;
}

認証トークン:

/**
 * HybridAuth authentication token.
 */
class HybridAuthToken extends AbstractToken
{
/**
 * @var string
 */
private $providerAdapter;

/**
 * Constructor.
 * 
 * @param string $providerAdapter The HybridAuth provider adapter name
 * @param string $user            The provided user identifier, or a UserInterface instance
 *                                or an object implementing a __toString method.
 * @param array  $roles           An array of roles
 */
public function __construct($providerAdapter, $user, array $roles = array())
{
    parent::__construct($roles);

    $this->providerAdapter = $providerAdapter;

    $this->setUser($user);

    parent::setAuthenticated(count($roles) > 0);
}

/**
 * {@inheritDoc}
 */
public function getCredentials()
{
    return '';
}

/**
 * Return the HybridAuth provider adapter name.
 * 
 * @return string
 */
public function getProviderAdapter()
{
    return $this->providerAdapter;
}

/**
 * {@inheritDoc}
 */
public function serialize()
{
    return serialize(array(
        $this->providerAdapter,
        parent::serialize()
    ));
}

/**
 * {@inheritDoc}
 */
public function unserialize($serialized)
{
    list(
        $this->providerAdapter,
        $parent,
    ) = unserialize($serialized);

    parent::unserialize($parent);
}

}

ユーザー プロバイダー エンティティ ("user_provider" mysql テーブル):

/**
 * @ORM\Entity
 * @ORM\Table("user_provider")
 */
class UserProvider implements UserProviderInterface
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 * 
 * @access protected
 * @var    integer
 */
protected $id;

/**
 * @ORM\OneToOne(targetEntity="Security\UserBundle\Entity\User")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
 * 
 * @access protected
 * @var    UserInterface
 */
protected $user;

/**
 * @ORM\Column(type="string", length=50, name="provider_id")
 * 
 * @access protected
 * @var    integer
 */
protected $providerId;

/**
 * @ORM\Column(type="string", length=255, name="provided_id")
 * 
 * @access protected
 * @var    integer
 */
protected $providedId;

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

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

/**
 * {@inheritDoc}
 */
public function setUser(UserInterface $user)
{
    $this->user = $user;
    return $this;
}

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

/**
 * {@inheritDoc}
 */
public function setProviderId($providerId)
{
    $this->providerId = $providerId;
    return $this;
}

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

/**
 * {@inheritDoc}
 */
public function setProvidedId($providedId)
{
    $this->providedId = $providedId;
    return $this;
}

}

ユーザー エンティティ ("user" mysql テーブル):

/**
 * @ORM\Entity
 * @ORM\Table("user")
 */
class User implements UserInterface
{
/**
 * @ORM\Id
 * @ORM\Column(type="integer")
 * @ORM\GeneratedValue(strategy="AUTO")
 * 
 * @access protected
 * @var    integer
 */
protected $id;

/**
 * @ORM\Column(type="string", length=255)
 * 
 * @access protected
 * @var    string
 */
protected $email;

/**
 * @ORM\Column(name="email_canonical", type="string", length=255, unique=true)
 * 
 * @access protected
 * @var    string
 */
protected $emailCanonical;

/**
 * @access protected
 * @var    string
 */
protected $plainPassword;

/**
 * @ORM\Column(type="string", length=255, nullable=true)
 * 
 * @access protected
 * @var    string
 */
protected $password;

/**
 * @ORM\Column(name="first_name", type="string", length=64)
 * 
 * @access protected
 * @var    string
 */
protected $firstName;

/**
 * @ORM\Column(name="last_name", type="string", length=64)
 * 
 * @access protected
 * @var    string
 */
protected $lastName;

/**
 * @ORM\Column(name="created_at", type="datetime")
 * 
 * @access protected
 * @var    DateTime
 */
protected $createdAt;

/**
 * @ORM\Column(name="last_login", type="datetime", nullable=true)
 * 
 * @access protected
 * @var    DateTime
 */
protected $lastLogin;

/**
 * @ORM\Column(name="confirmation_token", type="string", length=255, nullable=true)
 * 
 * @access protected
 * @var    string
 */
protected $confirmationToken;

/**
 * @ORM\Column(name="password_requested_at", type="datetime", nullable=true)
 * 
 * @access protected
 * @var    DateTime
 */
protected $passwordRequestedAt;

/**
 * @ORM\Column(type="boolean")
 * 
 * @access protected
 * @var    boolean
 */
protected $enabled;

/**
 * @ORM\Column(type="boolean")
 * 
 * @access protected
 * @var    boolean
 */
protected $locked;

/**
 * @ORM\Column(type="boolean")
 * 
 * @access protected
 * @var    boolean
 */
protected $expired;

/**
 * @ORM\Column(name="expires_at", type="datetime", nullable=true)
 * 
 * @access protected
 * @var    DateTime
 */
protected $expiresAt;

/**
 * @ORM\Column(name="credentials_expired", type="boolean")
 * 
 * @access protected
 * @var    boolean
 */
protected $credentialsExpired;

/**
 * @ORM\Column(name="credentials_expire_at", type="datetime", nullable=true)
 * 
 * @access protected
 * @var    DateTime
 */
protected $credentialsExpireAt;

/**
 * @ORM\Column(type="array")
 * 
 * @access protected
 * @var    array
 */
protected $roles;


/**
 * Constructor
 */
public function __construct()
{
    $this->createdAt          = new DateTime();
    $this->enabled            = true;
    $this->locked             = false;
    $this->expired            = false;
    $this->credentialsExpired = false;
    $this->roles              = array();
}

/**
 * Return the primary identifier.
 * 
 * @return integer
 */
public function getId()
{
    return $this->id;
}

/**
 * Return the username.
 * 
 * @return string
 */
public function getUsername()
{
    return $this->getEmail();
}

/**
 * Return the email address.
 * 
 * @return string
 */
public function getEmail()
{
    return $this->email;
}

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

/**
 * Return the canonical email address in search and sort queries.
 * 
 * @return string
 */
public function getEmailCanonical()
{
    return $this->email;
}

/**
 * Set the canonical email address in search and sort queries.
 * 
 * @param  string $emailCanonical
 * @return User
 */
public function setEmailCanonical($emailCanonical)
{
    $this->emailCanonical = $emailCanonical;
    return $this;
}

/**
 * Returns the plain password.
 * 
 * @return string
 */
public function getPlainPassword()
{
    return $this->plainPassword;
}

/**
 * Sets the plain password.
 * 
 * @param  string $plainPassword
 * @return self
 */
public function setPlainPassword($plainPassword)
{
    $this->plainPassword = $plainPassword;
    return $this;
}

/**
 * Returns the password.
 * 
 * @return string
 */
public function getPassword()
{
    return $this->password;
}

/**
 * Sets the password.
 * 
 * @param  string $password
 * @return self
 */
public function setPassword($password)
{
    $this->password = $password;
    return $this;
}

/**
 * Erases the credentials.
 * 
 * @return null
 */
public function eraseCredentials()
{
    $this->plainPassword = null;
    return $this;
}

/**
 * Returns the salt.
 * 
 * @return null
 */
public function getSalt()
{
    return null;
}

/**
 * Returns the first name.
 * 
 * @return string
 */
public function getFirstName()
{
    return $this->firstName;
}

/**
 * Sets the first name.
 * 
 * @param  string $firstName
 * @return self
 */
public function setFirstName($firstName)
{
    $this->firstName = $firstName;
    return $this;
}

/**
 * Returns the last name.
 * 
 * @return string
 */
public function getLastName()
{
    return $this->lastName;
}

/**
 * Sets the last name.
 * 
 * @param  string $lastName
 * @return self
 */
public function setLastName($lastName)
{
    $this->lastName = $lastName;
    return $this;
}

/**
 * Retruns created at time.
 * 
 * @return DateTime
 */
public function getCreatedAt()
{
    if (! $this->createdAt) {
        $this->setCreatedAt(new DateTime);
    }
    return $this->createdAt;
}

/**
 * Sets created at time.
 * 
 * @param  DateTime $createdAt
 * @return self
 */
public function setCreatedAt(DateTime $createdAt)
{
    $this->createdAt = $createdAt;
    return $this;
}

/**
 * Returns the last login time.
 * 
 * @return DateTime
 */
public function getLastLogin()
{
    return $this->lastLogin;
}

/**
 * Sets the last login time.
 * 
 * @param  DateTime $lastLogin
 * @return self
 */
public function setLastLogin(DateTime $lastLogin)
{
    $this->lastLogin = $lastLogin;
    return $this;
}

/**
 * Returns the confirmation token.
 * 
 * @return string
 */
public function getConfirmationToken()
{
    return $this->confirmationToken;
}

/**
 * Sets the confirmation token.
 * 
 * @param  string $confirmationToken
 * @return self
 */
public function setConfirmationToken($confirmationToken)
{
    $this->confirmationToken = $confirmationToken;
    return $this;
}

/**
 * Return the password request at time.
 * 
 * @return  DateTime
 */
public function getPasswordRequestedAt()
{
    return $this->passwordRequestedAt;
}

/**
 * Sets the password requested at time.
 * 
 * @param  DateTime $passwordRequestedAt
 * @return self
 */
public function setPasswordRequestedAt(DateTime $passwordRequestedAt)
{
    $this->passwordRequestedAt = $passwordRequestedAt;
    return $this;
}

/**
 * Checks whether the user is enabled.
 * 
 * @return boolean
 */
public function isEnabled()
{
    return $this->enabled;
}

/**
 * Sets the enabled status of the user.
 * 
 * @param  boolean $enabled
 * @return self
 */
public function setEnabled($enabled)
{
    $this->enabled = $enabled;
    return $this;
}

/**
 * Checks whether the user is locked.
 * 
 * @return boolean
 */
public function isLocked()
{
    return ! $this->isAccountNonLocked();
}

/**
 * Checks whether the user is locked.
 * 
 * @return boolean
 */
public function isAccountNonLocked()
{
    return ! $this->locked;
}

/**
 * Sets the locked status of the user.
 * 
 * @param  boolean $locked
 * @return self
 */
public function setLocked($locked)
{
    $this->locked = $locked;
    return $this;
}

/**
 * Checks whether the user is expired.
 * 
 * @return boolean
 */
public function isExpired()
{
    return ! $this->isAccountNonExpired();
}

/**
 * Checks whether the user is expired.
 * 
 * @return boolean
 */
public function isAccountNonExpired()
{
    if (true === $this->expired) {
        return false;
    }

    if (null !== $this->expiresAt && $this->expiresAt->getTimestamp() < time()) {
        return false;
    }

    return true;
}

/**
 * Sets the expired status of the user.
 * 
 * @param  boolean $expired
 * @return self
 */
public function setAccountExpired($expired)
{
    $this->expired = $expired;
    return $this;
}

/**
 * Returns the expired at time.
 * 
 * @return DateTime
 */
public function getExpiredAt()
{
    return $this->expiresAt;
}

/**
 * Sets the expired at time.
 * 
 * @param  DateTime $expiresAt
 * @return self
 */
public function setExpiredAt($expiresAt)
{
    $this->expiresAt = $expiresAt;
    return $this;
}

/**
 * Check whether the user's credentials (password) has expired.
 * 
 * @return boolean
 */
public function isCredentialsExpired()
{
    return ! $this->isCredentialsNonExpired();
}

/**
 * Check whether the user's credentials (password) has expired.
 * 
 * @return boolean
 */
public function isCredentialsNonExpired()
{
    if (true === $this->credentialsExpired) {
        return false;
    }

    if (null !== $this->credentialsExpireAt && $this->credentialsExpireAt->getTimestamp() < time()) {
        return false;
    }

    return true;
}

/**
 * Set the user's credentials (password) expired status.
 * 
 * @param  boolean $credentialsExpired
 * @return self
 */
public function setCredentialsExpired($credentialsExpired)
{
    $this->credentialsExpired = $credentialsExpired;
}

/**
 * Return the credentials expired at time.
 * 
 * @return DateTime
 */
public function getCredentialsExpiredAt()
{
    return $this->credentialsExpireAt;
}

/**
 * Set the credentials expired at time.
 * 
 * @param  DateTime $credetialsExpiredAt
 * @return User
 */
public function setCredentialsExpiredAt($credentialsExpiredAt)
{
    $this->credentialsExpiredAt = $credentialsExpiredAt;
    return $this;
}

/**
 * Return list fo roles.
 * 
 * @return array
 */
public function getRoles()
{
    $roles = array_merge($this->roles, array('ROLE_USER'));

    /*foreach ($this->getGroups() as $group)
    {
        $roles = array_merge($roles, $group->getRoles());
    }*/

    return array_unique($roles);
}

/**
 * Compares this user to another to determine if they are the same.
 * 
 * @todo: Maybe we should refresh user in listener, to prevent logout after making changes?
 * 
 * @param  UserInterface $user
 * @return boolean True if equal, False otherwise.
 */
public function isEqualTo(SymfonyUserInterface $user)
{
    return
        md5($user->getUsername()) == md5($this->getUsername()) &&
        md5(serialize($user->getRoles())) == md5(serialize($this->getRoles()));
}

/**
 * @see \Serializable::serialize()
 */
public function serialize()
{
    return serialize(array(
        $this->id,
        $this->email,
        $this->emailCanonical,
        $this->plainPassword,
        $this->password,
        $this->firstName,
        $this->lastName,
        $this->createdAt,
        $this->lastLogin,
        $this->confirmationToken,
        $this->passwordRequestedAt,
        $this->enabled,
        $this->locked,
        $this->expired,
        $this->expiresAt,
        $this->credentialsExpired,
        $this->credentialsExpireAt,
        $this->roles,
    ));
}

/**
 * @see \Serializable::unserialize()
 */
public function unserialize($serialized)
{
    //$data = unserialize($serialized);
    // add a few extra elements in the array to ensure that we have enough keys when unserializing
    // older data which does not include all properties.
    //$data = array_merge($data, array_fill(0, 2, null));

    list (
        $this->id,
        $this->email,
        $this->emailCanonical,
        $this->plainPassword,
        $this->password,
        $this->firstName,
        $this->lastName,
        $this->createdAt,
        $this->lastLogin,
        $this->confirmationToken,
        $this->passwordRequestedAt,
        $this->enabled,
        $this->locked,
        $this->expired,
        $this->expiresAt,
        $this->credentialsExpired,
        $this->credentialsExpireAt,
        $this->roles,
    ) = unserialize($serialized);
}
}

@edit 2: 認証の直後にイベントをキャッチしてそこからユーザーを取得し、getId() メソッドを呼び出すと、id 1 が返されます。したがって、認証プロセスに問題はないと思います...

自分の認証アダプターではなく、認証アダプターで UsernamePasswordToken を返すと、同じことが起こります。getId() を 0 として返します。

4

0 に答える 0