在Symfony 4中验证登录表单后,会话中没有错误,也没有用户

在Symfony 4中验证登录表单后,会话中没有错误,也没有用户,symfony,symfony4,Symfony,Symfony4,我试图在symfony4中创建一个简单的登录表单(遵循以下文档:) 我在数据库中有一个用户。 如果在登录表单中输入错误的凭据,则会收到错误的凭据错误消息。 但是,如果我输入正确的凭据,我将被重定向到主页(默认行为),但没有启动会话,则用户不在会话中 这是我正在使用的SecurityController: <?php namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use

我试图在symfony4中创建一个简单的登录表单(遵循以下文档:)

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

这是我正在使用的SecurityController:

<?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,
        ));
    }
}
树枝:

 {% 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 %}
{%extends'base.html.twig%}
{%block body%}
{%if错误%}
{{error.messageKey | trans(error.messageData,'security')}
{%endif%}
用户名:
密码:
登录
{%endblock%}
我看过这个问题:

但这并不能解决问题

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


干杯。

EqualTableInterface出现了一个问题,导致了这类问题。老实说,我不完全理解它为什么会这样做。但它是身份验证过程中的一种检查,以查看用户是否在请求之间进行了某种更改

更新:假设管理员在用户登录时重置了用户密码。如果您没有检查更改的密码,则用户可以继续使用旧密码。由你决定你想要什么样的行为。序列化密码并使用默认的EqualTableInterface实现将强制用户再次登录

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

// 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]);
}
修复您的用户::getRoles,它应该可以工作

另一种方法是实现EqualTableInterface

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;
}

使用这种方法,不需要序列化密码。这两种方法似乎都很好。

EqualTableInterface存在一个问题,导致了此类问题。老实说,我不完全理解它为什么会这样做。但它是身份验证过程中的一种检查,以查看用户是否在请求之间进行了某种更改

更新:假设管理员在用户登录时重置了用户密码。如果您没有检查更改的密码,则用户可以继续使用旧密码。由你决定你想要什么样的行为。序列化密码并使用默认的EqualTableInterface实现将强制用户再次登录

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

// 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]);
}
修复您的用户::getRoles,它应该可以工作

另一种方法是实现EqualTableInterface

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;
}

使用这种方法,不需要序列化密码。这两种方法似乎都很管用。

首先要摆脱http_基本行。你看到页面底部的配置栏了吗?去掉了http_的基本行。是的,我在页面底部有一个配置栏,所以你不会得到任何错误转储。配置文件栏没有显示登录的用户?没错,没有错误,用户是:匿名的。您不需要主防火墙下的模式属性,尽管我认为这不是问题。在代码方面,您还有什么没有向我们展示的吗?从去掉http_基本行开始。你看到页面底部的配置栏了吗?去掉了http_的基本行。是的,我在页面底部有一个配置栏,所以你不会得到任何错误转储。配置文件栏没有显示登录的用户?没错,没有错误,用户是:匿名的。您不需要主防火墙下的模式属性,尽管我认为这不是问题。在代码方面还有什么您没有向我们展示的吗?非常感谢@Cerad!这就解决了问题。在这个问题上花了几个小时!非常感谢@Cerad!这就解决了问题。在这个问题上花了几个小时!