简体   繁体   中英

How to encode password while creating a user with Sonata Admin (Symfony 4)?

I'm trying to encode the plainPassword field with Sonata Admin when creating a User. I am not using FOSUserBundle like in this issue . Here is my UserAdmin class :

<?php
// src/Admin/UserAdmin.php
namespace App\Admin;

use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Sonata\AdminBundle\Form\Type\ModelType;
use App\Entity\Image;

class UserAdmin extends AbstractAdmin
{
    protected function configureFormFields(FormMapper $formMapper) {
        $formMapper
            ->add('username', TextType::class)
            ->add('email', EmailType::class)
            ->add('plainPassword', TextType::class)
            ->add('avatar', ModelType::class, [
                'class' => Image::class,
                'property' => 'image',
            ])
        ;
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper) {
        $datagridMapper->add('username')
            ->add('avatar', null, [], EntityType::class, [
                'class'    => Image::class,
                'choice_label' => 'image',
            ])
        ;
    }

    protected function configureListFields(ListMapper $listMapper) {
        $listMapper
            ->addIdentifier('username')
        ;
    }

And my services.yaml contains the following :

admin.user:
        class: App\Admin\UserAdmin
        arguments: [~, App\Entity\User, ~]
        tags:
            - { name: sonata.admin, manager_type: orm, label: User }
        public: true

I don't know if I have to override preUpdate method like in this example and prePersist method or not.

My security.yaml begins like this :

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    # https://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
    providers:
        #in_memory: { memory: ~ }
        my_db_provider:
            entity:
                class: App\Entity\User

I found a solution : write some code in prePersist method. My configureFormFields method has a little bit changed but with no consequences :

protected function configureFormFields(FormMapper $formMapper) {
    $formMapper
        ->add('username', TextType::class)
        ->add('email', EmailType::class)
        ->add('plainPassword', RepeatedType::class, array(
            'type' => PasswordType::class,
            'first_options' => array('label' => 'Password'),
            'second_options' => array('label' => 'Password confirmation')
        ))
        ->add('avatar', ModelType::class, [
            'class' => Image::class,
            'property' => 'image',
        ])
    ;
}

And finally my prePersist method :

public function prePersist($object) { // $object is an instance of App\Entity\User as specified in services.yaml
    $plainPassword = $object->getPlainPassword();
    $container = $this->getConfigurationPool()->getContainer();
    $encoder = $container->get('security.password_encoder');
    $encoded = $encoder->encodePassword($object, $plainPassword);

    $object->setPassword($encoded);
}

Usually the password encoding takes place right after submitting (and validating) the form. Maybe you have to duplicate two lines of code for the encryption itself in the new and update methods in your user controller class, but that should be all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM