Symfony3 自定义用户提供程序不起作用

Symfony3 Custom User Provider doesn't work

我尝试按照 Symfony 文档实现所有内容,但身份验证似乎根本不起作用。看看我到底做了什么:

security.yml

security:
    encoders:
        AppBundle\Entity\StUser:
            algorithm: bcrypt
            cost: 12

    providers:
        our_db_provider:
            entity:
                class: AppBundle:Entity:StUser

    firewalls:
        user_secured_area:
            pattern:   ^/([a-z]{2})/account
            provider: our_db_provider
            form_login:
                login_path: login
                check_path: login_check
                csrf_token_generator: security.csrf.token_manager
        default:
            anonymous: ~
            http_basic: ~

StUser.php实体

namespace AppBundle\Entity;

class StUser implements UserInterface
{
    private $id;
    private $firstName;
    private $lastName;
    private $password;
    private $username;
    private $isAdmin = '0';
    private $confirmed;
    private $created = 'CURRENT_TIMESTAMP';
    private $status = '1';

    public function getId()
    {
        return $this->id;
    }

    public function setFirstName($firstName)
    {
        $this->firstName = $firstName;

        return $this;
    }

    public function getFirstName()
    {
        return $this->firstName;
    }

    public function setLastName($lastName)
    {
        $this->lastName = $lastName;

        return $this;
    }

    public function getLastName()
    {
        return $this->lastName;
    }

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

        return $this;
    }

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

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

        return $this;
    }

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

    public function setIsAdmin($isAdmin)
    {
        $this->isAdmin = $isAdmin;

        return $this;
    }

    public function getIsAdmin()
    {
        return $this->isAdmin;
    }

    public function setConfirmed($confirmed)
    {
        $this->confirmed = $confirmed;

        return $this;
    }

    public function getConfirmed()
    {
        return $this->confirmed;
    }

    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    public function getCreated()
    {
        return $this->created;
    }

    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

    public function getStatus()
    {
        return $this->status;
    }

    /* ==== Additional =================================================== */
    public function __construct($username, $password, $salt, array $roles)
    {
        $this->username = $username;
        $this->password = $password;
        /* $this->salt = $salt; */
        /* $this->roles = $roles; */
    }

    public function getRoles()
    {
        return null;
    }

    public function getSalt()
    {
        return null;
    }

    public function eraseCredentials()
    {

    }
}

UserRepository.php 存储库:

namespace AppBundle\Repository;

use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Doctrine\ORM\EntityRepository;

class UserRepository extends EntityRepository implements UserLoaderInterface
{
    public function loadUserByUsername($username)
    {
        return $this->createQueryBuilder('u')
            ->where('u.username = :username OR u.email = :email')
            ->setParameter('username', $username)
            ->setParameter('email', $username)
            ->getQuery()
            ->getOneOrNullResult();
    }
}

AccountController.php

namespace AccountBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class AccountController extends Controller
{
    /**
     * @Route("{_lang}/login", name="login", requirements={"_lang": "pl"})
     */
    public function loginAction(Request $request, $_lang = '')
    {
        $helper = $this->get('security.authentication_utils');
        $error = $helper->getLastAuthenticationError();

        var_dump( $error );

        return $this->render('account/login.html.twig', array(
            'projects' => "",
            'lang' => "pl",
            'allLangs' => "",
            'mainLang' => "",
            'meta_title' => "test",
            'meta_description' => "",
            'meta_keywords' => "",
            'meta_robots' => "",
            'image_src' => "",
            'social_title' => "",
            'social_description' => "",
            'social_url' => "",
            'aaaa' => $helper,

            /* 'last_username' => $lastUsername,
            'error'         => $error, */
        ));
    }
}

login.html.twig 查看

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

        <label for="password">Password:</label>
        <input type="password" id="password" name="_password" />
        
        <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">

        <button type="submit">login</button>
    </form>
{% endblock %}

没有任何反应,$helper 和 $error 为空/null,我在日志中找不到任何内容。我错过了什么。提前致谢。

在您的 security.yml 中,您需要添加具有默认值的 anonymous 键并修复 provider 键:

security.yml

security:
    encoders:
        AppBundle\Entity\StUser:
            algorithm: bcrypt
            cost: 12
    providers:
        our_db_provider:
            entity:
                class: AppBundle:StUser # not necessary to put 'Entity' here if your entities are in the Entity Folder
    firewalls:
        user_secured_area:
            anonymous: ~
            pattern:   ^/([a-z]{2})/account
            provider: our_db_provider
            form_login:
                login_path: login
                check_path: login_check
                csrf_token_generator: security.csrf.token_manager

接下来,在您的 AccountController 文件中,您为什么不使用特殊的路由参数 _locale?请阅读:Special Routing Parameters.

然后你在你的路由前加上 locale 参数,就像这样:

AccountController.php

namespace AccountBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;

class AccountController extends Controller
{
    /**
     * @Route("/{_locale}/login", name="login", requirements={"_locale": "pl"})
     */
    public function loginAction(Request $request, $_lang = '')
    {
        $helper = $this->get('security.authentication_utils');
        $error = $helper->getLastAuthenticationError();

        var_dump( $error );

        return $this->render('account/login.html.twig', array(
            'projects' => "",
            'lang' => "pl",
            'allLangs' => "",
            'mainLang' => "",
            'meta_title' => "test",
            'meta_description' => "",
            'meta_keywords' => "",
            'meta_robots' => "",
            'image_src' => "",
            'social_title' => "",
            'social_description' => "",
            'social_url' => "",
            'aaaa' => $helper,

            /* 'last_username' => $lastUsername,
            'error'         => $error, */
        ));
    }
}

不知道你用的是哪种实体映射策略。注释还是 xml ? 看看这个(来自文档):

Don't forget to add the repository class to the mapping definition of your entity.

我试过了,但没有成功。似乎从未调用过任何自定义代码。

我更新了security.yml(当我设置匿名:~,然后它允许用户在未经授权的情况下打开例如帐户页面):

security:
    encoders:
        AppBundle\Entity\StUser:
            algorithm: bcrypt
            cost: 12

    providers:
        our_db_provider:
            entity:
                class: AppBundle:StUser

    firewalls:
        user_secured_area:
            pattern:   ^/([a-z]{2})/account
            # anonymous: ~
            provider: our_db_provider
            form_login:
                login_path: login
                check_path: login_check
                csrf_token_generator: security.csrf.token_manager
        default:
            anonymous: ~
            http_basic: ~

我还更新了用户实体:

StUser.orm.yml实体:

AppBundle\Entity\StUser:
    type: entity
    table: st_user
    repositoryClass: AppBundle\Repository\UserRepository
    indexes:
        status_username_password:
            columns:
                - status
                - username
                - password
        status_is_admin_username_password:
            columns:
                - status
                - is_admin
                - username
                - password
    id:
        id:
            type: integer
            nullable: false
            options:
                unsigned: false
            id: true
            generator:
                strategy: IDENTITY
    fields:
        firstName:
            type: string
            nullable: true
            length: 255
            options:
                fixed: false
            column: first_name
        lastName:
            type: string
            nullable: true
            length: 255
            options:
                fixed: false
            column: last_name
        password:
            type: string
            nullable: true
            length: 255
            options:
                fixed: false
        username:
            type: string
            nullable: true
            length: 255
            options:
                fixed: false
        isAdmin:
            type: boolean
            nullable: false
            options:
                default: '0'
            column: is_admin
        confirmed:
            type: datetime
            nullable: true
        created:
            type: datetime
            nullable: false
            options:
                default: CURRENT_TIMESTAMP
        status:
            type: boolean
            nullable: false
            options:
                default: '0'
    lifecycleCallbacks: {  }