doucan8246326
2016-10-17 05:59
浏览 39
已采纳

Symfony - 已登录的用户未填写所有字段

I'am using Symfony 2.8 and Doctrine and I have security.yml configured to point to the User class which implements UserInterface. My ORM schema is in YAML.

The problem: - In database the user has also specified "email" field, Symfony for LOGGED USER is not filling up that field and also "password" field is empty.

screenshot

When I do $this->get('doctrine.orm.entity_manager')->clear(User::class); then the entity manager is fetching correctly the entity. But when the entity is COMING FROM SESSION, then it's incorrect.

The problem is also that when I try to fetch a fresh entity from database using find() on a repository then, the incorrect element from session is fetched when I will not use the $em->clear(User::class)

Question: - How to tell Symfony/Doctrine to construct my entity in that way that it will have all fields filled up, so it will become persistable?

<?php

namespace XXX\AppBundle\Model\Entity;

use XXX\AppBundle\Model\Entity\Server\Logging;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * User
 */
class User implements UserInterface
{
    /**
     * @var integer $id
     */
    protected $id;

    /**
     * @var string $username
     */
    protected $username;

    /**
     * @var string $email
     */
    protected $email;

    /**
     * @var string $password
     */
    protected $password;

    /**
     * @var array $roles
     */
    protected $roles = array();

    /**
     * @var \Doctrine\Common\Collections\Collection $logEvents
     */
    protected $logEvents;

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

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

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

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

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

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

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

    /**
     * Returns the roles or permissions granted to the user for security.
     */
    public function getRoles()
    {
        $roles = $this->roles;

        // guarantees that a user always has at least one role for security
        if (empty($roles)) {
            $roles[] = 'ROLE_USER';
        }

        return array_unique($roles);
    }

    public function setRoles(array $roles)
    {
        $this->roles = $roles;
    }

    /**
     * Returns the salt that was originally used to encode the password.
     */
    public function getSalt()
    {
        // See "Do you need to use a Salt?" at http://symfony.com/doc/current/cookbook/security/entity_provider.html
        // we're using bcrypt in security.yml to encode the password, so
        // the salt value is built-in and you don't have to generate one

        return;
    }

    /**
     * Removes sensitive data from the user.
     */
    public function eraseCredentials()
    {
        $this->password = null;
        $this->email    = null;
    }

    /**
     * Appends an entry to administration log
     *
     * @param \XXX\AppBundle\Model\Entity\Server\Logging $logEvent
     * @return $this
     */
    public function appendLog(Server\Logging $logEvent)
    {
        if (!$this->logEvents->contains($logEvent))
        {
            $this->logEvents->add($logEvent);
        }

        return $this;
    }

    /**
     * Remove a log entry from the history
     *
     * @param \XXX\AppBundle\Model\Entity\Server\Logging $logEvent
     * @return $this
     */
    public function clearLogEntry(Server\Logging $logEvent)
    {
        $this->logEvents->removeElement($logEvent);

        return $this;
    }
}

And ORM configuration:

XXX\AppBundle\Model\Entity\User:
    type: entity
    table: users
    repositoryClass: XXX\AppBundle\Model\Repository\UserRepository
    id:
        id:
            type: integer
            scale: 0
            length: null
            unique: false
            nullable: false
            precision: 0
            id: true
            generator:
                strategy: IDENTITY
    fields:
        username:
            type: string
            scale: 0
            length: null
            unique: true
            nullable: false
            precision: 0
        email:
            type: string
            scale: 0
            length: null
            unique: true
            nullable: false
            precision: 0
        password:
            type: string
            scale: 0
            length: null
            unique: false
            nullable: false
            precision: 0
        roles:
            type: json_array
            scale: 0
            length: null
            unique: false
            nullable: false
            precision: 0
    oneToMany:
        logEvents:
            targetEntity: XXX\AppBundle\Model\Entity\Server\Logging
            cascade:
                - remove
                - persist
            fetch: LAZY
            mappedBy: author
            inversedBy: null
            orphanRemoval: false
            orderBy: null
    lifecycleCallbacks: {  }

Thank you for your time. have a great day :-)

  • 写回答
  • 好问题 提建议
  • 追加酬金
  • 关注问题
  • 收藏
  • 邀请回答

1条回答 默认 最新

  • doulupian8725 2016-10-17 08:58
    已采纳

    You implemented the UserInterface::eraseCredentials() method in a way that it unsets the email and the password:

    public function eraseCredentials()
    {
        $this->password = null;
        $this->email    = null;
    }
    

    Symfony will invoke this method before serializing the object to save it in the session.

    The UserInterface::eraseCredentials() is meant to remove sensitive data from the user object so it does not end up in for example the session files, but there is no real need to remove the email, like you are doing. A better example would be if you are storing the plaintext version of the user's password somewhere on this object, this is something you would never want to end up in session files.

    评论
    解决 无用
    打赏 举报

相关推荐 更多相似问题