Symfony 4 EasyAdminBundle:编码和保存普通密码的问题

问题描述 投票:1回答:1

这些是我与Symfony合作的第一步。我尝试使用Symfony 4.4中的Easyadmin Bundle实现一个简单的用户管理。我在symfony.com上遵循了该教程,并且大部分都能正常运行(注册表单,后端登录,后端安全性,来自数据库的用户后端列表)。

我的问题是在Easyadmin后端中创建和更新用户。当我尝试创建新用户时,我看到正确的字段,确实输入了一些数据,如果单击“保存更改”,则会引发以下错误:

An exception occurred while executing 'INSERT INTO app_users (username, email, roles, password, is_active) VALUES (?, ?, ?, ?, ?)' with params ["testname", "[email protected]", "a:1:{i:0;s:9:\"ROLE_USER\";}", null, 1]:
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'password' cannot be null

Column'password'不能为null很清楚:我需要为其提供一些编码的密码字符串。

我认为我输入的纯密码字段中的数据未通过我的用户实体中的setPassword()方法进行编码和/或处理。

据我所知,有些答案和Symfony文档应该可以自动运行!?我不知道。我试图创建一个扩展EasyAdminController的AdminController并将其挂在用户实体持久化的某个位置,但是我无法使其正常工作。 (类似这样的内容:https://stackoverflow.com/a/54749433

我如何处理/编码保存在数据库密码字段中的普通密码?


用户实体:

// /src/Entity/User.php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;

/**
 * @ORM\Table(name="app_users")
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 * @UniqueEntity("username")
 * @UniqueEntity("email")
 */
class User implements AdvancedUserInterface, \Serializable
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=254, unique=true)
     * @Assert\NotBlank(groups={"edit"})
     */
    private $username;

    /**
     * @ORM\Column(type="string", length=254, unique=true)
     * @Assert\NotBlank()
     * @Assert\Email(groups={"edit"})
     */
    private $email;

    /**
     * @ORM\Column(type="array")
     */
    private $roles;

    /**
     * @Assert\Length(max=4096)
     */
    private $plainPassword;

    /**
     * @ORM\Column(type="string", length=64)
     */
    private $password;

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive;

    public function __construct(){
        $this->roles = array('ROLE_USER');
        $this->isActive = true;
    }

    public function getId(){
        return $this->id;
    }

    public function getUsername(){
        return $this->username;
    }

    public function setUsername($username){
        $this->username = $username;
    }

    public function getEmail(){
        return $this->email;
    }

    public function setEmail($email){
        $this->email = $email;
    }

    public function getIsActive(){
        return $this->isActive;
    }

    public function setIsActive($is_active){
        $this->isActive = $is_active;
    }

    public function getRoles(){
        return $this->roles;
    }

    public function setRoles($roles){
        $roles[] = 'ROLE_USER';
        $this->roles = $roles;
    }

    public function getPlainPassword(){
        return $this->plainPassword;
    }

    public function setPlainPassword($password){
        $this->plainPassword = $password;
    }

    public function getPassword()
    {
        return $this->password;
    }

    public function setPassword($password){
        $this->password = $password;
    }

    public function getSalt(){
        return null;
    }

    public function eraseCredentials(){}

    public function isAccountNonExpired(){
        return true;
    }

    public function isAccountNonLocked(){
        return true;
    }

    public function isCredentialsNonExpired(){
        return true;
    }

    public function isEnabled(){
        return $this->isActive;
    }

    /** @see \Serializable::serialize() */
    public function serialize(){
        return serialize(array(
            $this->id,
            $this->username,
            $this->email,
            $this->password,
            $this->isActive,
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized){
        list (
            $this->id,
            $this->username,
            $this->email,
            $this->password,
            $this->isActive,
        ) = unserialize($serialized, array('allowed_classes' => false));
    }
}

Security.yaml:

# /config/packages/security.yaml
security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    providers:
        users_in_memory: { memory: null }
        our_db_provider:
            entity:
                class: App\Entity\User
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            anonymous: true
            pattern: ^/
            provider: our_db_provider
            form_login:
                login_path: login
                check_path: login
                default_target_path: account
                always_use_default_target_path: true
                csrf_token_generator: security.csrf.token_manager
            logout:
                path: /logout
                target: /login
    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
        - { path: ^/account, roles: ROLE_USER }
        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY }

Easyadmin.yaml:

# /config/packages/easy_admin.yaml
easy_admin:
    design:
        menu:
            - { entity: User, label: 'Benutzerverwaltung', icon: 'user' }
    entities:
        User:
            class: App\Entity\User
            label: 'Benutzer'
            password_encoding: { algorithm: 'bcrypt', cost: 12 }
            form:
                form_options: { validation_groups: ['Default'] }
                fields:
                    - { type: 'group', icon: 'address-card', label: 'Informationen', css_class: 'col-lg-6' }
                    - username
                    - email
                    - { type: 'group', icon: 'user-shield', label: 'Rechteverwaltung', css_class: 'col-lg-6' }
                    - { property: 'is_active', type: 'checkbox' }
                    - { property: 'roles', type: 'choice', type_options: { multiple: true, choices: { 'ROLE_USER': 'ROLE_USER', 'ROLE_ADMIN': 'ROLE_ADMIN' } } }
                    - { type: 'group', icon: 'user-lock', label: 'Passwort', css_class: 'col-lg-6' }
                    - { property: 'plainPassword', type: 'text', type_options: { required: false } }
php symfony symfony4
1个回答
0
投票

我现在可以回答我自己的问题:

解决方案:我只是忘记了在Easyadmin路由中引用控制器:

# config/routes/easy_admin.yaml
easy_admin_bundle:
    resource: 'App\Controller\AdminController'
    prefix: /admin
    type: annotation

这里是有相同问题的每个人的完整控制者:

// src/Controller/AdminController.php
namespace App\Controller;

use App\Entity\User;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use EasyCorp\Bundle\EasyAdminBundle\Controller\EasyAdminController;

class AdminController extends EasyAdminController
{
    private $passwordEncoder;

    public function __construct(UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->passwordEncoder = $passwordEncoder;
    }

    private function encodeUserPlainPassword($user)
    {
        $plainPassword = $user->getPlainPassword();

        if (!empty($plainPassword)) {
            $encoded = $this->passwordEncoder->encodePassword($user, $plainPassword);
            $user->setPassword($encoded);
        }
    }

    public function persistEntity($user)
    {
        $this->encodeUserPlainPassword($user);
        parent::persistEntity($user);
    }

    public function updateEntity($user)
    {
        $this->encodeUserPlainPassword($user);
        parent::updateEntity($user);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.