问题描述
-
信息:我是Symfony和Sonata的新手
-
我的目标:仅加密数据库端的密码。我将能够清楚地显示此密码。所有这些都针对实体服务中的字段密码。
-
我正在尝试什么? :我尝试创建使用
bcrypt
加密的Doctrine侦听器安全性:
编码器: App \ Entity \ Service:bcrypt
-
这是我的App \ Doctrine中的HashPasswordLisetener.php(在App \ Admin \ ServiceAdmin.php中configureFormField函数的$ formMapper中,我有这样的一行->add('password')
)
<?php
namespace App\Doctrine;
use App\Entity\Service;
use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
class HashPasswordListener implements EventSubscriber
{
private $passwordEncoder;
public function __construct(UserPasswordEncoderInterface $passwordEncoder)
{
$this->passwordEncoder = $passwordEncoder;
}
public function prePersist(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof Service) {
return;
}
$this->encodePassword($entity);
}
public function preUpdate(LifecycleEventArgs $args)
{
$entity = $args->getEntity();
if (!$entity instanceof Service) {
return;
}
$this->encodePassword($entity);
$em = $args->getEntityManager();
$meta = $em->getClassMetadata(get_class($entity));
$em->getUnitOfWork()->recomputeSingleEntityChangeSet($meta,$entity);
}
public function getSubscribedEvents()
{
return ['prePersist','preUpdate'];
}
/**
* @param Service $entity
*/
private function encodePassword(Service $entity)
{
if (!$entity->getPlainPassword()) {
return;
}
$encoded = $this->passwordEncoder->encodePassword(
$entity,$entity->getPlainPassword()
);
$entity->setPassword($encoded);
}
}
这是App \ Entity中的服务实体
<?php
namespace App\Entity;
use App\Admin\AbstractAdmin;
use App\Repository\ServiceRepository;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Timestampable\Traits\TimestampableEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* @ORM\Entity(repositoryClass=ServiceRepository::class)
*/
class Service implements UserInterface
{
use TimestampableEntity;
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(type="string",length=255)
*/
private $name;
/**
* @ORM\Column(type="string",length=255)
*/
private $password;
/**
* @ORM\Column(type="text",nullable=true,length=255)
*/
private $comment;
/**
* @ORM\Column(type="string",length=255)
*/
private $identifier;
private $plainPassword;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getPassword(): ?string
{
return $this->password;
}
public function setPassword(string $password): self
{
$this->password = $password;
return $this;
}
public function getComment(): ?string
{
return $this->comment;
}
public function setComment(?string $comment): self
{
$this->comment = $comment;
return $this;
}
public function getIdentifier(): ?string
{
return $this->identifier;
}
public function setIdentifier(string $identifier): self
{
$this->identifier = $identifier;
return $this;
}
/**
* @return mixed
*/
public function getPlainPassword()
{
return $this->plainPassword;
}
/**
* @param mixed $plainPassword
*/
public function setPlainPassword($plainPassword): void
{
$this->plainPassword = $plainPassword;
$this->password = null;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function getSalt()
{
}
public function eraseCredentials()
{
$this->plainPassword = null;
}
public function getUsername()
{
return $this->identifier;
}
}
也是我的sonata_admin.yaml:
app.doctrine.hash_password_listener:
class: App\Doctrine\HashPasswordListener
autowire : true
tags:
- { name: doctrine.event_subscriber,connection: 'default' }
-
我的问题: 我了解函数encodePassword在第一个参数(而不是我的实体)中等待UserInterface和在第二个参数中进行加密的密码,但我不知道谁在使用该UserInterface?我应该在哪里打电话呢?为拿到它,为实现它 ?发送吗?
我想我提供了很多细节,但是如果我忘记了什么,请随时注意我^^ 谢谢您花时间至少阅读。
解决方法
我遇到了问题,但是我正在编码哈希类型的代码,但是我正在寻找一种加密方法。但是这是我如何处理可工作的哈希的方法:
-
步骤1:在我的服务实体中实现 UserInterface
-
第2步:在侦听器中将 UserPasswordEncoderInterface 替换为 UserPasswordEncoder
-
步骤2.5:添加了
UserInterface
所需的所有功能,例如eraseCredidential
getSalt()
。有关详细信息,请参见:this -
步骤3:添加一个
的getUsername
return this->identifier
-
步骤4:在表单字段中使用
plainPasswords
代替password
-
第5步:添加了一个提供程序:
app_user:
entity: class: 'App\Entity\Service' property: 'identifier'
-
步骤6:将
TextType::class
用于plainPassword
表单字段类型,并用{固定use
: Symfony \ Component \ Form \ Extension \ Core \ Type \ TextType -
第7步:正常工作
(特别感谢@msg对我的帮助很大)