Symfony 注册新用户 getUser returns null 处理请求

Symfony Registering New User getUser returns null on handling request

尝试使用表单和 ajax 请求注册新用户(因为它将成为模态表单)并在尝试验证表单时遇到障碍。当请求得到处理时,它声明用户在密码验证器中为空。并且不明白如何通过这个或允许这条路线允许用户注册。

我试过更新安全 yaml,更改路由

加载初始页面的控制器

<?php

declare(strict_types=1);

namespace App\Controller;

use App\Entity\User;
use App\Form\RegistrationFormType;
use App\Repository\UserRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;

class HomeController extends AbstractController
{
    /**
     * Undocumented function
     * 
     * @Route("/", name="index")
     *
     * @return Response
     */
    public function index(UserRepository $userRepository): Response
    {
        $user = new User();
        $registerForm = $this->createForm(RegistrationFormType::class, $user);

        //dd($userRepository->getUserByUserIdentifier('samueldurw@outlook.com'));

        $pageContent = [
            'registrationForm' => $registerForm->createView(),
        ];

        return $this->render('base.html.twig', $pageContent);
    }
}

处理请求的控制器

<?php

declare(strict_types=1);

namespace App\Controller\Security;

use App\Entity\User;
use App\Form\RegistrationFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;

/**
 * Undocumented class
 */
class RegistrationController extends AbstractController
{
    /**
     * Registering a new user.
     * 
     * @Route("/ajax/registration", name="registration")
     *
     * @return Response
     */
    public function register(Request $request, EntityManagerInterface $entityManager): Response
    {
        $user = new User();
        $registrationForm = $this->createForm(RegistrationFormType::class, $user);
        
        $registrationForm->handleRequest($request);
        //dd("I'm here after request");
        if ($registrationForm->isSubmitted() && $registrationForm->isValid()) {
            $entityManager->persist($user);
            $entityManager->flush();
            
            return new RedirectResponse($request->headers->get('referer'));
        }

        return new RedirectResponse($request->headers->get('referer'));
    }
}

将创建的用户实体

<?php

declare(strict_types=1);

namespace App\Entity;

use App\Entity\Trait\TimestampableEntity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert;
use Symfony\Component\Validator\Constraints as Assert;

/**
 *
 * @ORM\Table(name="tblUser")
 * @ORM\Entity(repositoryClass=UserRepository::class)
 */
class User implements UserInterface
{
    use TimestampableEntity;

    /**
     * @var int
     *
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(name="intUserId", type="integer", nullable=false)
     */
    private int $id;

    /**
     * @var string
     *
     * @ORM\Column(name="strFirstName", type="string", nullable=false)
     *
     * @Assert\NotBlank
     * @Assert\Length(
     *        min = 2,
     *        max = 50,
     *        minMessage = "Your first name must be at least {{ limit}} characters long",
     *        maxMessage = "Your first name cannot be longer than {{ limit }} characters"
     * )
     */
    private string $firstName;

    /**
     * @var string
     *
     * @ORM\Column(name="strLastName", type="string", nullable=false)
     *
     * @Assert\NotBlank
     * @Assert\Length(
     *        min = 2,
     *        max = 50,
     *        minMessage = "Your first name must be at least {{ limit}} characters long",
     *        maxMessage = "Your first name cannot be longer than {{ limit }} characters"
     * )
     */
    private string $lastName;

    /**
     * @var string
     *
     * @ORM\Column(name="strUsername", type="string", nullable=false)
     *
     * @Assert\Unique()
     * @Assert\Length(
     *        min = 2,
     *        max = 15,
     *        minMessage = "Your first name must be at least {{ limit}} characters long",
     *        maxMessage = "Your first name cannot be longer than {{ limit }} characters"
     * )
     */
    private string $username;

    /**
     * @var string
     *
     * @ORM\Column(name="strPassword", type="string", nullable=false)
     *
     * @Assert\NotNull()
     *
     * @SecurityAssert\UserPassword(message = "Password is incorrect, please try again")
     */
    private string $password;

    /**
     * @var string
     *
     * @ORM\Column(name="strEmail", type="string", nullable=false)
     *
     * @Assert\Unique()
     * @Assert\Email()
     */
    private string $email;

    /**
     * @var bool
     * 
     *  @ORM\Column(name="bolAcceptTermsConditions", type="boolean", nullable=false)
     * 
     * @Assert\NotNull()
     */
    private bool $acceptTermsAndConditions;

    /**
     * @var bool
     * 
     *  @ORM\Column(name="bolAcceptPrivacyPolicy", type="boolean", nullable=false)
     * 
     * @Assert\NotNull()
     */
    private bool $acceptPrivacyPolicy;

    /**
     * @var bool
     * 
     * @ORM\Column(name="bolEmailOptIn", type="boolean", nullable=false)
     * 
     * @Assert\NotNull()
     */
    private bool $emailOptIn;

    /**
     * @return string
     */
    public function getFullName(): string
    {
        return $this->firstName . " " . $this->lastName;
    }

    /**
     * @return string
     */
    public function getFirstName(): string
    {
        return $this->firstName;
    }

    /**
     * @return string
     */
    public function getLastName(): string
    {
        return $this->lastName;
    }

    /**
     * @return string
     */
    public function getEmail(): string
    {
        return $this->email;
    }

    public function getRoles()
    {
        // TODO: Implement getRoles() method.
    }

    /**
     * @return string
     */
    public function getPassword(): string
    {
        return $this->password;
    }

    /**
     * Undocumented function
     *
     * @return boolean
     */
    public function getAcceptTermsAndConditions(): bool
    {
        return $this->acceptTermsAndConditions;
    }

    /**
     * Undocumented function
     *
     * @return boolean
     */
    public function getAcceptPrivacyPolicy(): bool
    {
        return $this->acceptPrivacyPolicy;
    }

    /**
     * Undocumented function
     *
     * @return boolean
     */
    public function getEmailOptIn(): bool
    {
        return $this->emailOptIn;
    }

    /**
     * @return void
     */
    public function getSalt()
    {
        // TODO: Implement getSalt() method.
    }

    public function eraseCredentials()
    {
        // TODO: Implement eraseCredentials() method.
    }

    /**
     * @return string
     */
    public function getUserIdentifier(): string
    {
        return $this->username;
    }

    /**
     * @return string
     */
    public function getUsername(): string
    {
        return $this->username;
    }

    /**
     * Undocumented function
     *
     * @param string $firstname
     * 
     * @return void
     */
    public function setFirstName(string $firstname)
    {
        $this->firstName = $firstname;
    }

    /**
     * Undocumented function
     *
     * @param string $lastName
     * @return void
     */
    public function setLastName(string $lastName)
    {
        $this->lastName = $lastName;
    }

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

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

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

    public function setAcceptTermsAndConditions(bool $accepted)
    {
        $this->acceptTermsAndConditions = $accepted;
    }

    public function setAcceptPrivacyPolicy(bool $accepted)
    {
        $this->acceptPrivacyPolicy = $accepted;
    }

    public function setEmailOptIn(bool $accepted)
    {
        $this->emailOptIn = $accepted;
    }

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

表单包含所有字段并映射到用户实体。努力确定如何在不对整个注册系统进行重大修改的情况下使它正常工作。

security.yaml

security:
    encoders:
        App\Entity\User:
            algorithm: auto

    enable_authenticator_manager: true

    password_hashers:
        Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'

    providers:
    #users_in_memory: { memory: null }
        app_user_provider:
            entity:
                class: App\Entity\User
                property: email
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        main:
            lazy: true
            provider: app_user_provider
            custom_authenticator:
                - App\Security\LoginFormAuthenticator
            logout:
                path: logout

    # Easy way to control access for large sections of your site
    # Note: Only the *first* access control that matches will be used
    access_control:
        # - { path: ^/admin, roles: ROLE_ADMIN }
        # - { path: ^/profile, roles: ROLE_USER }
        - { path: /registration, roles: PUBLIC_ACCESS}

已修复,现在可以添加新用户,将对他们的定向位置进行一些更改,但这超出了这个问题的范围。

注册控制器:需要修复 return 并显示表单中存在的错误,并在登录后重定向到主页。

<?php

declare(strict_types=1);

namespace App\Controller\Security;

use App\Entity\User;
use App\Form\RegistrationFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;

/**
 * Undocumented class
 */
class RegistrationController extends AbstractController
{
    /**
     * Registraion method
     * 
     * @Route("/registration", name="registration")
     *
     * @return Response
     */
    public function register(Request $request, EntityManagerInterface $entityManager,
    UserPasswordHasherInterface $passwordHasher): Response
    {
        $user = new User();
        $registrationForm = $this->createForm(RegistrationFormType::class, $user);

        $registrationForm->handleRequest($request);

        dd($user->getUsername());
        if ($registrationForm->isSubmitted() && $registrationForm->isValid()) {
            $password = $passwordHasher->hashPassword($user, $user->getPlainPassword());
            $user->setPassword($password);

            //dd($user->getPlainPassword(), $user->getPassword());

            $entityManager->persist($user);
            $entityManager->flush();

            $pageContent = [
                'registrationForm' => $registrationForm->createView(),
            ];
            
            return $this->render('base.html.twig', $pageContent);
        }

        $pageContent = [
            'registrationForm' => $registrationForm->createView(),
            'formErrors' => $registrationForm->getErrors()
        ];
        
        return new RedirectResponse($request->headers->get('referer'));
    }
}

用户实体:在断言的工作方式及其周围的限制方面犯了一些错误,因为不必要而被删除。

<?php

declare(strict_types=1);

namespace App\Entity;

use App\Entity\Trait\TimestampableEntity;
use Carbon\Carbon;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert;
use Symfony\Component\Validator\Constraints as Assert;

/**
 *
 * @ORM\Table(name="tblUser")
 * @ORM\Entity(repositoryClass=UserRepository::class)
 */
class User implements UserInterface
{
    use TimestampableEntity;

    /**
     * @var int
     *
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(name="intUserId", type="integer", nullable=false)
     */
    private int $id;

    /**
     * @var string
     *
     * @ORM\Column(name="strFirstName", type="string", nullable=false)
     *
     * @Assert\NotBlank
     * @Assert\Length(
     *        min = 2,
     *        max = 50,
     *        minMessage = "Your first name must be at least {{ limit}} characters long",
     *        maxMessage = "Your first name cannot be longer than {{ limit }} characters"
     * )
     */
    private string $firstName;

    /**
     * @var string
     *
     * @ORM\Column(name="strLastName", type="string", nullable=false)
     *
     * @Assert\NotBlank
     * @Assert\Length(
     *        min = 2,
     *        max = 50,
     *        minMessage = "Your first name must be at least {{ limit}} characters long",
     *        maxMessage = "Your first name cannot be longer than {{ limit }} characters"
     * )
     */
    private string $lastName;

    /**
     * @var string
     *
     * @ORM\Column(name="strUsername", type="string", nullable=false)
     *
     * @Assert\Length(
     *        min = 2,
     *        max = 15,
     *        minMessage = "Your first name must be at least {{ limit}} characters long",
     *        maxMessage = "Your first name cannot be longer than {{ limit }} characters"
     * )
     */
    private string $username;

    /**
     * @var string
     *
     * @ORM\Column(name="strPassword", type="string", nullable=false)
     *
     */
    private string $password;

    /**
     * Plain string password used for form registration
     *
     * @var string
     * 
     */
    private string $plainPassword;

    /**
     * @var string
     *
     * @ORM\Column(name="strEmail", type="string", nullable=false)
     *
     * @Assert\NotNull()
     * @Assert\Email()
     */
    private string $email;

    /**
     * @var bool
     * 
     *  @ORM\Column(name="bolAcceptTermsConditions", type="boolean", nullable=false)
     * 
     * @Assert\NotNull()
     */
    private bool $acceptTermsAndConditions;

    /**
     * @var bool
     * 
     *  @ORM\Column(name="bolAcceptPrivacyPolicy", type="boolean", nullable=false)
     * 
     * @Assert\NotNull()
     */
    private bool $acceptPrivacyPolicy;

    /**
     * @var bool
     * 
     * @ORM\Column(name="bolEmailOptIn", type="boolean", nullable=false)
     * 
     * @Assert\NotNull()
     */
    private bool $emailOptIn;

    public function __construct()
    {
        $this->dateAdded = Carbon::now();
    }

    /**
     * @return string
     */
    public function getFullName(): string
    {
        return $this->firstName . " " . $this->lastName;
    }

    /**
     * @return string
     */
    public function getFirstName(): string
    {
        return $this->firstName;
    }

    /**
     * @return string
     */
    public function getLastName(): string
    {
        return $this->lastName;
    }

    /**
     * @return string
     */
    public function getEmail(): string
    {
        return $this->email;
    }

    public function getRoles()
    {
        // TODO: Implement getRoles() method.
    }

    /**
     * @return string
     */
    public function getPassword(): string
    {
        return $this->password;
    }

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

    /**
     * Undocumented function
     *
     * @return boolean
     */
    public function getAcceptTermsAndConditions(): bool
    {
        return $this->acceptTermsAndConditions;
    }

    /**
     * Undocumented function
     *
     * @return boolean
     */
    public function getAcceptPrivacyPolicy(): bool
    {
        return $this->acceptPrivacyPolicy;
    }

    /**
     * Undocumented function
     *
     * @return boolean
     */
    public function getEmailOptIn(): bool
    {
        return $this->emailOptIn;
    }

    /**
     * @return void
     */
    public function getSalt()
    {
        // TODO: Implement getSalt() method.
    }

    public function eraseCredentials()
    {
        // TODO: Implement eraseCredentials() method.
    }

    /**
     * @return string
     */
    public function getUserIdentifier(): string
    {
        return $this->username;
    }

    /**
     * @return string
     */
    public function getUsername(): string
    {
        return $this->username;
    }

    /**
     * Undocumented function
     *
     * @param string $firstname
     * 
     * @return void
     */
    public function setFirstName(string $firstname)
    {
        $this->firstName = $firstname;
    }

    /**
     * Undocumented function
     *
     * @param string $lastName
     * @return void
     */
    public function setLastName(string $lastName)
    {
        $this->lastName = $lastName;
    }

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

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

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

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

    public function setAcceptTermsAndConditions(bool $accepted)
    {
        $this->acceptTermsAndConditions = $accepted;
    }

    public function setAcceptPrivacyPolicy(bool $accepted)
    {
        $this->acceptPrivacyPolicy = $accepted;
    }

    public function setEmailOptIn(bool $accepted)
    {
        $this->emailOptIn = $accepted;
    }

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

将在注册后添加自动登录,但不会在那个阶段添加。 Symfony 文档、symfony 转换和 Bogdan George Moza