*封面图像最初是由geralt进行的,并以非常感谢。
概括
使用EasyAdmin捆绑包,您可以轻松创建管理面板:
好吧,对于用户实体,鉴于它具有密码字段,您必须在存储安全之前先进行哈希。
这篇文章显示了如何使用EasyAdmin实施。
环境
如何哈希密码
源代码
这是一个例子。
像这样修改src/Controller/Admin/UserCrudController.php
:
<?php
namespace App\Controller\Admin;
use App\Entity\User;
use EasyCorp\Bundle\EasyAdminBundle\Config\{Action, Actions, Crud, KeyValueStore};
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
use EasyCorp\Bundle\EasyAdminBundle\Field\{IdField, EmailField, TextField};
use Symfony\Component\Form\Extension\Core\Type\{PasswordType, RepeatedType};
use Symfony\Component\Form\{FormBuilderInterface, FormEvent, FormEvents};
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
class UserCrudController extends AbstractCrudController
{
public function __construct(
public UserPasswordHasherInterface $userPasswordHasher
) {}
public static function getEntityFqcn(): string
{
return User::class;
}
public function configureActions(Actions $actions): Actions
{
return $actions
->add(Crud::PAGE_EDIT, Action::INDEX)
->add(Crud::PAGE_INDEX, Action::DETAIL)
->add(Crud::PAGE_EDIT, Action::DETAIL)
;
}
public function configureFields(string $pageName): iterable
{
$fields = [
IdField::new('id')->hideOnForm(),
EmailField::new('email'),
];
$password = TextField::new('password')
->setFormType(RepeatedType::class)
->setFormTypeOptions([
'type' => PasswordType::class,
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => '(Repeat)'],
'mapped' => false,
])
->setRequired($pageName === Crud::PAGE_NEW)
->onlyOnForms()
;
$fields[] = $password;
return $fields;
}
public function createNewFormBuilder(EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createNewFormBuilder($entityDto, $formOptions, $context);
return $this->addPasswordEventListener($formBuilder);
}
public function createEditFormBuilder(EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createEditFormBuilder($entityDto, $formOptions, $context);
return $this->addPasswordEventListener($formBuilder);
}
private function addPasswordEventListener(FormBuilderInterface $formBuilder): FormBuilderInterface
{
return $formBuilder->addEventListener(FormEvents::POST_SUBMIT, $this->hashPassword());
}
private function hashPassword() {
return function($event) {
$form = $event->getForm();
if (!$form->isValid()) {
return;
}
$password = $form->get('password')->getData();
if ($password === null) {
return;
}
$hash = $this->userPasswordHasher->hashPassword($this->getUser(), $password);
$form->getData()->setPassword($hash);
};
}
}
描述
我会将其分解为几个部分。
Constructor Property Promotion
此样式是有效的,因为PHP 8.0。
public function __construct(
public UserPasswordHasherInterface $userPasswordHasher
) {}
当您的php版本在其之前,请按照下面的方式写下:
private $userPasswordHasher;
public function __construct(
UserPasswordHasherInterface $userPasswordHasher
) {
$this->userPasswordHasher = $userPasswordHasher;
}
添加菜单
这是可选的。菜单被添加到索引页面并编辑。
public function configureActions(Actions $actions): Actions
{
return $actions
->add(Crud::PAGE_EDIT, Action::INDEX)
->add(Crud::PAGE_INDEX, Action::DETAIL)
->add(Crud::PAGE_EDIT, Action::DETAIL)
;
}
生成密码字段
configureFields
是configure the fields to display的EasyAdmin的功能之一。
在这里,密码字段定义为passwordType和repotedType。另外,作为一个unmapped field,可以防止在设置null以不更改密码的情况下进行验证例外。
public function configureFields(string $pageName): iterable
{
$fields = [
IdField::new('id')->hideOnForm(),
EmailField::new('email'),
];
$password = TextField::new('password')
->setFormType(RepeatedType::class)
->setFormTypeOptions([
'type' => PasswordType::class,
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => '(Repeat)'],
'mapped' => false,
])
->setRequired($pageName === Crud::PAGE_NEW)
->onlyOnForms()
;
$fields[] = $password;
return $fields;
}
处理事件
在这里,Symfony表单事件与EasyAdmin事件处理程序一起使用。这是因为到目前为止EasyAdmin's events不支持处理形式验证。
public function createNewFormBuilder(EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createNewFormBuilder($entityDto, $formOptions, $context);
return $this->addPasswordEventListener($formBuilder);
}
public function createEditFormBuilder(EntityDto $entityDto, KeyValueStore $formOptions, AdminContext $context): FormBuilderInterface
{
$formBuilder = parent::createEditFormBuilder($entityDto, $formOptions, $context);
return $this->addPasswordEventListener($formBuilder);
}
private function addPasswordEventListener(FormBuilderInterface $formBuilder): FormBuilderInterface
{
return $formBuilder->addEventListener(FormEvents::POST_SUBMIT, $this->hashPassword());
}
哈希密码
这是Symfony的PasswordHasher的Hashing密码的关键部分。
当未输入密码时,跳过字段。
hash hash,并将字段添加到实体datað
private function hashPassword() {
return function($event) {
$form = $event->getForm();
if (!$form->isValid()) {
return;
}
$password = $form->get('password')->getData();
if ($password === null) {
return;
}
$hash = $this->userPasswordHasher->hashPassword($this->getUser(), $password);
$form->getData()->setPassword($hash);
};
}
就是这样。
如果这篇文章中的代码和描述会帮助您:)