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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 Python时间序列如何拟合疏系数模型
  • ¥15 求学软件的前人们指明方向🥺
  • ¥50 如何增强飞上天的树莓派的热点信号强度,以使得笔记本可以在地面实现远程桌面连接
  • ¥20 双层网络上信息-疾病传播
  • ¥50 paddlepaddle pinn
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services