4

从 symfony 4 开始,我想创建一个简单的身份验证表单。我创建了一个用户类(标识符是电子邮件字段,而不是“用户名”,我创建了一个类控制器并配置了 security.yml 文件。

我用这个静态方法创建了一些用户:(对于测试,默认密码是'test')

class User implements \Serializable, UserInterface
{
// ...
  public static function new_alea($email, $isActive = false, $password="test"){
    $instance = new self();
    $instance->isActive = $isActive;
    $instance->email = $email;

    $brypt = new BCryptPasswordEncoder(4);
    $instance->password = $brypt->encodePassword($password, null);

    return $instance;
  }
// ...
}

它的工作,我的数据库中有一些用户使用加密密码。

但是当我进入表单页面并尝试登录(填写电子邮件/密码字段并单击提交按钮)时,我收到错误“凭据无效”。

在此处输入图像描述

这个错误是什么意思?如何/在哪里调试我的代码以查找为什么会发生此错误?

下面,我的代码的主要部分,也许你会看到一个我没有看到的错误:

security.yaml 文件:

security:
    encoders:
        App\Entity\User:
            algorithm: bcrypt
    providers:
        my_db_provider:
            entity:
                class: App\Entity\User
                property: email
    firewalls:
        main:
            provider: my_db_provider
            anonymous: ~
            form_login:
                login_path: login
                check_path: login
    role_hierarchy:
        # ...

用户实体类:

class User implements \Serializable, UserInterface
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     * @ORM\Column(type="integer")
     */
    private $id;

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

    /**
     * @ORM\Column(type="string", length=255, unique=true)
     */
    private $email;

    /**
     * @ORM\Column(name="is_active", type="boolean")
     */
    private $isActive;

    private $plainPassword;

    public static function new_alea($email, $isActive = false, $password="coucou"){
        $instance = new self();
        $instance->isActive = $isActive;
        $instance->email = $email;

        $brypt = new BCryptPasswordEncoder(4);
        $instance->password = $brypt->encodePassword($password, null);

        return $instance;
    }

    public function eraseCredentials() {
        $this->plainPassword = null;
    }

    public function serialize() {
        return serialize(array(
            $this->id,
            $this->email,
            $this->password,
        ));
    }

    public function unserialize($serialized) {
        list (
            $this->id,
            $this->email,
            $this->password,
            ) = unserialize($serialized);
    }

    public function getRoles() {
        return array('ROLE_ADMIN');
    }

    public function getPassword() {
        return $this->password;
    }

    public function setPassword($password) {
        $this->password = $password;
    }

    public function getUsername() {
        return $this->email;
    }

    public function setUsername($email) {
        $this->email = $email;
    }

    public function getPlainPassword() {
        return $this->plainPassword;
    }

    public function setPlainPassword($plainPassword): void {
        $this->plainPassword = $plainPassword;
    }

    // and others getters/setters

登录控制器:

class LoginController extends Controller
{
    /**
     * @Route("/login", name="login")
     */
    public function login(Request $request, AuthenticationUtils $authUtils)
    {
        // get the login error if there is one
        $error = $authUtils->getLastAuthenticationError();

        // last username entered by the user
        $email = $authUtils->getLastUsername();

        return $this->render('frontend/log/login.html.twig', array(
            'email' => $email,
            'error' => $error,
        ));
    }
}

和模板 login.html.twig 文件:

{% 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="email">Email:</label>
        <input type="text" id="email" name="_email" value="{{ email }}" />

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

        {#
            If you want to control the URL the user
            is redirected to on success (more details below)
            <input type="hidden" name="_target_path" value="/account" />
        #}

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

{% endblock body %}
4

5 回答 5

0

我遇到了类似的问题,我通过将密码从纯文本更改为编码版本来解决。

# I create users by fixtures
$user->setEmail('admin@admin');
$user->setPassword('admin'); // Wrong

$user->setPassword($this->passwordEncoder->encodePassword(
    $user,
    'admin'
)); // Correct

官方参考:https ://symfony.com/doc/master/bundles/DoctrineFixturesBundle/index.html#accessing-services-from-the-fixtures

于 2018-12-12T08:32:33.750 回答
0

只需在“前端{{ error }}”错误消息下方输出即可获得完整的堆栈跟踪等...

于 2018-07-26T11:45:19.663 回答
0

使用两个具有相同功能名称和不同标签名称的路由器路径,以便在用户名和密码正确时它会移动到您的登录路径。当您的密码或用户名无效时,它将移动到另一个路径。

例子:

index:
 path: /
 controller: App\Controller\DefaultController::login

login:
  path: /login
  controller: App\Controller\DefaultController::login
于 2018-05-07T14:03:30.477 回答
0

在您的登录模板中,添加一个{{ dump(error) }}. 它包括真正的错误消息(通常就足够了),以及整个堆栈跟踪(如果需要)。并且格式比仅仅更好{{ error }}

{% if error %}
    {{  dump(error) }}
    <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
于 2018-09-10T13:11:57.233 回答
0

嗨,我今天遇到了同样的问题,对我来说,这是我在字符串密码中限制了字符数。所以密码错误,因为编码占用了太多字符。所以我删除了字符的限制并且它有效。

于 2018-07-12T20:26:06.640 回答