在 Symfony 4 中验证登录表单后没有错误并且会话中没有用户 [英] No error and no user in session after login form is validated in Symfony 4

查看:25
本文介绍了在 Symfony 4 中验证登录表单后没有错误并且会话中没有用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 Symfony 4 中制作一个简单的登录表单(遵循此文档:https://symfony.com/doc/current/security/form_login_setup.html).

I'm trying to make a simple login form in Symfony 4 (followed this documentation: https://symfony.com/doc/current/security/form_login_setup.html).

我在数据库中有一个用户.如果我在登录表单中输入错误的凭据,我会收到错误的凭据错误消息.但是如果我输入正确的凭据,我会被重定向到主页(默认行为)但没有启动会话,用户不在会话中.

I have a user in database. If I enter wrong credentials in the login form, I get wrong credentials error messages. But if I enter right credentials I get redirected to home (default behaviour) but no sessions is started, the user is not in session.

这是我正在使用的 SecurityController:

This is the SecurityController I'm using:

<?php
namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class SecurityController extends Controller
{
    /**
     * @Route("/login", name="login")
     */
    public function login(Request $request, AuthenticationUtils $authenticationUtils)
    {
        $error = $authenticationUtils->getLastAuthenticationError();

        $lastUsername = $authenticationUtils->getLastUsername();

        return $this->render('security/login.html.twig', array(
            'last_username' => $lastUsername,
            'error'         => $error,
        ));
    }
}

security.yaml 文件:

The security.yaml file:

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

providers:
    in_memory: { memory: ~ }
    quimly_db_provider:
        entity:
            class: App\Entity\User
            property: username

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false

    main:
        anonymous: ~

        pattern:    ^/
        http_basic: ~
        provider: quimly_db_provider
        form_login:
            login_path: login
            check_path: login

树枝:

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

{% block body %}

{% if error %}
    <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}

<form action="{{ path('login') }}" method="post">
    <label for="username">Username:</label>
    <input type="text" id="username" name="_username" value="{{ last_username }}" />

    <label for="password">Password:</label>
    <input type="password" id="password" name="_password" />

    <button type="submit">login</button>
</form>

{% endblock %}

我已经阅读了这个问题:如何创建symfony 4 登录验证表单

I have read this question: How to create a login authentification form with symfony 4

但这并不能解决问题.

如果有人对此有任何了解,将非常感谢您的帮助!

If anyone has any knowledge about this, help would be very much appreciated !

干杯.

推荐答案

EquatableInterface 存在一个问题,导致此类问题.老实说,我不完全理解为什么它会这样做.但它在身份验证过程中会检查用户是否在请求之间发生了某种变化.

There is an issue with something called the EquatableInterface that causes this sort of problems. To be honest, I don't understand fully why it does what it does. But it's something in the authentication process which checks to see if the user has somehow changed between requests.

更新:假设管理员在用户登录时重置了用户密码.如果您不检查更改的密码,则用户可以继续使用旧密码工作.由您决定您想要哪种行为.序列化密码并使用默认的 EquatableInterface 实现将强制用户再次登录.

Update: Assume an administrator reset's a user's password while the user is logged in. If you don't check for a changed password then the user can continue to work with the old password. It is up to you to decide which behavior you want. Serializing the password and using the default EquatableInterface implementation will force the user to log in again.

避免该问题的一种方法是序列化密码.

One way to avoid the issue is to serialize the password.

// App/Entity/User.php
public function serialize()
{
    //die('serialize');
    return serialize(array(
        $this->id,
        $this->username,
        $this->password
    ));
}

public function unserialize( $serialized )
{
    list (
        $this->id,
        $this->username,
        $this->password
        ) = unserialize($serialized, ['allowed_classes' => false]);
}

修复您的 User::getRoles,它应该可以工作了.

Fix your User::getRoles and it should work.

另一种方法是实现 EquatableInterface

The other approach is to implement the EquatableInterface

class User implements UserInterface, \Serializable, EquatableInterface

public function isEqualTo(UserInterface $user)
{
    //if ($this->password !== $user->getPassword()) {
    //    return false;
    //}

    //if ($this->salt !== $user->getSalt()) {
    //    return false;
    //}

    if ($this->username !== $user->getUsername()) {
        return false;
    }

    return true;
}

使用这种方法不需要序列化密码.无论哪种方式似乎都可以正常工作.

With this approach there is no need to serialize the password. Either way seems to work fine.

这篇关于在 Symfony 4 中验证登录表单后没有错误并且会话中没有用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆