在Symfony 4上验证用户身份的正确方法

时间:2018-08-06 11:50:01

标签: forms symfony twig bootstrap-4

我正在使用Symfony身份验证。我读了很多手册,但没有结果。我想了解如何使用bootstrap_4_layout.html.twig正确显示显示错误的登录表单。原因是我尝试登录时显示丑陋的消息invalid credentials。 因此,我的UserLoginType是:

class UserLoginType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array 
$options)
    {
        $builder
            ->add('username', TextType::class,
                ['constraints' => array(new Length(array('min' => 3)))])
            ->add('password', PasswordType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => User::class,
        ));
    }
}

我的security.yaml文件与文档中的完全一样: enter image description here

当然还有其他字段名称(因为我正在使用symfony形式进行渲染), 这是我的测试登录方法:

public function login(Request $request, AuthenticationUtils $authenticationUtils)
{
    $error = $authenticationUtils->getLastAuthenticationError();
    $lastUsername = $authenticationUtils->getLastUsername();
    $form = $this->createForm(UserLoginType::class);
    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        dump($form->getData());
        die();
    }
    return $this->render('Security/login.html.twig',
        ['form' => $form->createView(),
            'last_username' => $lastUsername,
            'error'        => $error,
        ]);
}

这是我的login.html.twig

{% extends 'layout.html.twig' %}

{% block title %}Login page{% endblock %}

{% block description %}This is login page{% endblock %}
{% form_theme form 'bootstrap_4_layout.html.twig' %}
{% block content %}
    <div class="container">
        {{ form_start(form) }}
        {{ form_widget(form) }}
        <input class="btn btn-primary" type="submit" value="Login" />
        {{ form_end(form) }}
    </div>
{% endblock %}

因此,当我尝试登录时: enter image description here

我如何得到这样的东西: enter image description here

2 个答案:

答案 0 :(得分:0)

由于Symfony处理身份验证,因此您将收到“无效的凭据”消息,而无需自己处理表单。从文档中:

不要让此控制器使您感到困惑。稍后您将看到,当用户提交表单时,安全系统会自动为您处理表单提交。如果用户提交了无效的用户名或密码,则此控制器将从安全系统读取表单提交错误,以便可以将其显示回给用户。

为什么在登录表单上会出现诸如“用户名应为3个字符或更多个字符”的错误?我认为登录表单不需要这些错误消息。

尽管如此,您也许可以使用以下方法自己验证请求:

$errors = $validator->validate($user);

然后将错误传递到您的视图或在表单中设置错误。

答案 1 :(得分:0)

框架(尤其是Symfony之类的框架)的美丽之处在于它们为您带来了许多“魔力”。需要登录吗?将带有字段的发布表单端点指向/ login / check。需要验证表格吗?只是添加约束?太美了。当试图将头缠绕在发生问题的地方时,这种美也可能成为问题。有许多方法可以验证用户身份。我几乎总是喜欢手动操作。像这样:-

// To-DO, get Username and Password from request
if (!$username || !$password) {
  throw error;
}

// Query DB for user example using.
$user = $em->findUserByUsernameOrEmail($username);

if (!$user) {
  throw 404 error;
}

// The juice of it

// Let get the password encoder and encode the submitted password to see if it matches
$encoder_service = $this->get('security.encoder_factory');
$encoder = $encoder_service->getEncoder($user);

if (!$encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt())) {
  throw bad password exception;
}

// We're good to go, the user with the name and password was found in the DB so let's log him/her in

// Get the security firewall name, and login the user
$providerKey = 'firewall_name'; // e.g main
$token = new UsernamePasswordToken($user, $password, $providerKey, $user->getRoles());
$this->get("security.token_storage")->setToken($token);

// Fire the login event to notify any listeners
$event = new InteractiveLoginEvent($request, $token);
$this->get("event_dispatcher")->dispatch("security.interactive_login", $event);

// Continue your logic

正如我说的,有很多方法可以给这只猫咪剥皮,所以要选择毒药。