首页 > 解决方案 > Symfony 验证器 dosnt 验证器正确验证器 dosnt 在重定向后保留用户

问题描述

最近我陷入了一个错误,我不知道为什么它不起作用我希望你们有一个想法。

所以关键是我想为我的管理员创建一个登录名,所以我创建它实体\App\Entity\Admin、控制器AdminController和身份验证器AdminLoginAuthentication,它在安全配置中保护访问点。

当我通过admin.1@yahoo.com登录时,登录成功重定向admin_dashboard,但关键是身份验证器不保留凭据,并且接入点重新将管理员重定向到登录。

另外,我看到了这个Symfony 4 登录表单:身份验证成功,但重定向后身份验证立即丢失并且它不起作用。

在这里你可以在登录中看到它应该是匿名的,它是(图片)

在这里你可以看到我已经登录但我仍然是匿名的(图片)

这是 Symfony-profiler,您可以看到登录成功验证(图片)

但是在成功验证并重定向到仪表板卷之后变得匿名 (图片)

由于接入点重定向回登录

为了更好地理解,请查看图片

这是我的security.yaml

security:
    encoders:
        App\Entity\Admin:
            algorithm: bcrypt

    providers:
        admin_provider:
            entity:
                class: App\Entity\Admin
                property: email
    firewalls:
        dev:
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false
        artist:
            anonymous: ~
            pattern: ^/admin
            provider: admin_provider
            guard:
                authenticators:
                    - App\Security\AdminLoginAuthenticator
            logout:
                path: admin_logout
    access_control:
        - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/admin/, roles: ROLE_ADMIN }

这是我来自Symfony FormBuilder 的登录表单- AdminLoginType

namespace App\Form\Admin;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;

class AdminLoginType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('username', EmailType::class, [
                'attr' => [
                    'class' => 'form-control form-control-solid h-auto py-6 px-6 rounded-lg',
                    'placeholder' => 'Username',
                    'autocomplete' => 'off',
                ]
            ])
            ->add('password', PasswordType::class, [
                'attr' => [
                    'class' => 'form-control form-control-solid h-auto py-6 px-6 rounded-lg',
                    'placeholder' => 'Password',
                ]
            ])
            ->add('submit', SubmitType::class, [
                'label' => 'Sign in',
                'attr' => [
                    'class' => 'btn btn-primary font-weight-bolder font-size-h6 px-8 py-4 my-3 mr-3',
                ]
            ]);
    }
}

这是我的身份验证器 AdminLoginAuthenticator

namespace App\Security;

use App\Entity\Admin;
use App\Form\Artist\AdminLoginType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Guard\Authenticator\AbstractFormLoginAuthenticator;
use Symfony\Component\Security\Http\Util\TargetPathTrait;

class AdminLoginAuthenticator extends AbstractFormLoginAuthenticator
{
    use TargetPathTrait;

    public const LOGIN_ROUTE = 'Admin_login';

    private $entityManager;

    private $urlGenerator;

    private $passwordEncoder;

    private $formFactory;

    public function __construct(EntityManagerInterface $entityManager, UrlGeneratorInterface $urlGenerator, UserPasswordEncoderInterface $passwordEncoder, FormFactoryInterface $formFactory)
    {
        $this->entityManager = $entityManager;
        $this->urlGenerator = $urlGenerator;
        $this->passwordEncoder = $passwordEncoder;
        $this->formFactory = $formFactory;
    }

    public function supports(Request $request)
    {
        return self::LOGIN_ROUTE === $request->attributes->get('_route')
            && $request->isMethod('POST');
    }

    public function getCredentials(Request $request)
    {
        $form = $this->formFactory->create(AdminLoginType::class);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $credentials = $form->getData();

            $request->getSession()->set(
                Security::LAST_USERNAME,
                $credentials['username']
            );

            return $credentials;
        }

        throw new CustomUserMessageAuthenticationException("Custom User Message Authentication Exception");
    }

    public function getUser($credentials, UserProviderInterface $userProvider)
    {
        $user = $this->entityManager->getRepository(Admin::class)->findOneBy(['email' => $credentials['username']]);

        if (!$user) {
            throw new CustomUserMessageAuthenticationException("Custom User Message Authentication Exception");
        }

        return $user;
    }

    public function checkCredentials($credentials, UserInterface $user)
    {
        if ($this->passwordEncoder->isPasswordValid($user, $credentials['password']))
            return true;

        return false;
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
    {
        return new RedirectResponse($this->urlGenerator->generate('admin_dashboard'));
    }

    protected function getLoginUrl()
    {
        return $this->urlGenerator->generate(self::LOGIN_ROUTE);
    }
}

这是我的管理员控制器

namespace App\Controller\Admin;

use App\Form\Artist\AdminForgetType;
use App\Form\Artist\AdminLoginType;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

/**
 * @Route("/admin")
 */
class AdminController extends AbstractController
{
    /**
     * @Route("/", name="admin_index")
     */
    public function index()
    {
         if ($this->getUser())
             return $this->redirectToRoute('admin_dashboard');

        return $this->redirectToRoute("admin_login");
    }

    /**
     * @Route("/login", name="admin_login")
     */
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();

        $admin_login_form = $this->createForm(ArtistLoginType::class, ["username" => $lastUsername]);
        $admin_forget_form = $this->createForm(ArtistForgetType::class);

        return $this->render('admin/login.html.twig', [
            'artist_login_form' => $admin_login_form->createView(),
            'artist_forget_form' => $admin_forget_form->createView(),
            'error' => $error,
        ]);
    }

    /**
     * @Route("/logout", name="admin_logout")
     */
    public function logout()
    {
        throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
    }
}

这是我的实体\ App\Entity\Admin扩展\App\Entity\User

namespace App\Entity;

use App\Repository\AdminRepository;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass=AdminRepository::class)
 */
class Admin extends User
{
    public function getRoles(): array
    {
        $roles = parent::getRoles();
        $roles[] = 'ROLE_ADMIN';

        return array_unique($roles);
    }
}

这是从我的界面UserModelInterface 实现\App\Entity\ User

namespace App\Entity;

use App\Repository\UserRepository;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\MappedSuperclass()
 */
class User implements UserModelInterface
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @ORM\Column(type="string", length=32)
     */
    protected $name;

    /**
     * @ORM\Column(type="string", length=32)
     */
    protected $family;

    /**
     * @ORM\Column(type="string", length=180)
     */
    protected $email;

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

    /**
     * @ORM\Column(type="date")
     */
    protected $birth;

    /**
     * @ORM\Column(type="integer")
     */
    protected $profile;

    /**
     * @ORM\Column(type="json")
     */
    protected $last_5_passwords = [];

    /**
     * @ORM\Column(type="datetime")
     */
    protected $last_password_update;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $register_date;

    /**
     * @ORM\Column(type="datetime")
     */
    protected $update_date;

    /**
     * @ORM\Column(type="json")
     */
    protected $roles = [];

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

    /**
     * @see UserModelInterface
     */
    public function getName(): ?string
    {
        return $this->name;
    }

    /**
     * @see UserModelInterface
     */
    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    /**
     * @see UserModelInterface
     */
    public function getFamily(): ?string
    {
        return $this->family;
    }

    /**
     * @see UserModelInterface
     */
    public function setFamily(string $family): self
    {
        $this->family = $family;

        return $this;
    }

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

    /**
     * @see UserModelInterface
     */
    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

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

    /**
     * @see UserModelInterface
     */
    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }

    /**
     * @see UserModelInterface
     */
    public function getBirth(): ?\DateTimeInterface
    {
        return $this->birth;
    }

    /**
     * @see UserModelInterface
     */
    public function setBirth(\DateTimeInterface $birth): self
    {
        $this->birth = $birth;

        return $this;
    }

    /**
     * @see UserModelInterface
     */
    public function getProfile(): ?int
    {
        return $this->profile;
    }

    /**
     * @see UserModelInterface
     */
    public function setProfile(int $profile): self
    {
        $this->profile = $profile;

        return $this;
    }

    /**
     * @see UserModelInterface
     */
    public function getLast5Passwords(): ?array
    {
        return $this->last_5_passwords;
    }

    /**
     * @see UserModelInterface
     */
    public function setLast5Passwords(array $last_5_passwords): self
    {
        $this->last_5_passwords = $last_5_passwords;

        return $this;
    }

    /**
     * @see UserModelInterface
     */
    public function getLastPasswordUpdate(): ?\DateTimeInterface
    {
        return $this->last_password_update;
    }

    /**
     * @see UserModelInterface
     */
    public function setLastPasswordUpdate(\DateTimeInterface $last_password_update): self
    {
        $this->last_password_update = $last_password_update;

        return $this;
    }

    /**
     * @see UserModelInterface
     */
    public function getRegisterDate(): ?\DateTimeInterface
    {
        return $this->register_date;
    }

    /**
     * @see UserModelInterface
     */
    public function setRegisterDate(\DateTimeInterface $register_date): self
    {
        $this->register_date = $register_date;

        return $this;
    }

    /**
     * @see UserModelInterface
     */
    public function getUpdateDate(): ?\DateTimeInterface
    {
        return $this->update_date;
    }

    /**
     * @see UserModelInterface
     */
    public function setUpdateDate(\DateTimeInterface $update_date): self
    {
        $this->update_date = $update_date;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        // guarantee every user at least has ROLE_USER
        $roles[] = 'ROLE_USER';

        return array_unique($roles);
    }

    /**
     * @see UserModelInterface
     */
    public function setRoles(array $roles): self
    {
        $this->roles = $roles;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function getSalt()
    {
        return null;
    }

    /**
     * @see UserInterface
     */
    public function getUsername()
    {
        return $this->email;
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials()
    {
        $this->password = null;
    }
}

这是从UserInterface扩展UserModelInterface

namespace App\Entity;

use Symfony\Component\Security\Core\User\UserInterface;

interface UserModelInterface extends UserInterface
{
    /**
     * @return string
     */
    public function getName();

    /**
     * @param string $name
     * @return self
     */
    public function setName(string $name);

    /**
     * @return string
     */
    public function getFamily();

    /**
     * @param string $family
     *
     * @return self
     */
    public function setFamily(string $family);

    /**
     * @return string
     */
    public function getEmail();

    /**
     * @param string $email
     * @return self
     */
    public function setEmail(string $email);

    /**
     * @return string
     */
    public function getPassword();

    /**
     * @param string $password
     * @return self
     */
    public function setPassword(string $password);

    /**
     * @return \DateTimeInterface
     */
    public function getBirth();

    /**
     * @param \DateTimeInterface $birth
     * @return self
     */
    public function setBirth(\DateTimeInterface $birth);

    /**
     * @return int
     */
    public function getProfile();

    /**
     * @param int $profile
     * @return self
     */
    public function setProfile(int $profile);

    /**
     * @return array
     */
    public function getLast5Passwords();

    /**
     * @param array $last_5_passwords
     * @return self
     */
    public function setLast5Passwords(array $last_5_passwords);

    /**
     * @return \DateTimeInterface
     */
    public function getLastPasswordUpdate();

    /**
     * @param \DateTimeInterface $last_password_update
     * @return self
     */
    public function setLastPasswordUpdate(\DateTimeInterface $last_password_update);

    /**
     * @return \DateTimeInterface
     */
    public function getRegisterDate();

    /**
     * @param \DateTimeInterface $register_date
     * @return self
     */
    public function setRegisterDate(\DateTimeInterface $register_date);

    /**
     * @return \DateTimeInterface
     */
    public function getUpdateDate();

    /**
     * @param \DateTimeInterface $update_date
     */
    public function setUpdateDate(\DateTimeInterface $update_date);

    /**
     * @param array $roles
     *
     * @return mixed
     */
    public function setRoles(array $roles);
}

标签: phpsymfonydoctrine-ormsymfony4symfony-forms

解决方案


我认为在您的 security.yaml 文件中您需要更改 access_control: - { path: ^/admin/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }

访问控制:-{ 路径:^/admin/login,角色:ROLE_ADMIN }


推荐阅读