forms - 在 Symfony 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,
));
}
}
当然还有其他字段名称(因为我使用 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 %}
解决方案
框架的美妙之处,尤其是像 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
正如我所说,有很多方法可以剥去这只猫的皮,所以选择你的毒药。
推荐阅读
- nlp - 让他用语法构建词汇表(CFG)
- python - pd.read_csv 如果逗号在括号内,则忽略它
- python - 如何组合两个 YOLOv5 模型?
- spring - Spring Boot MongoDB 云集群
- django - Nginx 在用于容器的 Azure Web App 的 Dockered Django 应用中找不到静态文件
- python - Python - 读取文本并写入 csv。将空列替换为默认的“N/A”值
- java - 等价于 java 中的 std::iota
- json - Flutter/Dart setState 不刷新文本小部件中的文本
- react-hooks - 如何在 apollo 客户端中获取值
- node.js - Node js Mysql Ininter加入多个数据库表