没有使用Doctrine的Symfony2身份验证(登录)?

3
我对Symfony和Doctrine都很陌生。在Symfony页面上,有一个关于如何构建sf2中登录流程的教程。我非常喜欢它,但是我不会使用Doctrine,也不想使用它(有很多东西在Doctrine中无法使用,如枚举等)。创建登录控制器、设置防火墙等方面解释得很清楚。但是,我想不用Doctrine来创建它...我有一个现有的数据库,并且我喜欢纯SQL。:-) 我怎样才能在UserInterface中使用纯SQL,让它能与sf2的内置登录一起工作呢?非常感谢!
2个回答

3

以下是我针对Symfony 3.0提出的一个解决方案。

由于我要实现一个已有的PostgreSQL数据库,并且想要重用已有的PHP代码,ORM在我的情况下不适用(反向工程需要太多时间)。因此,我一直在积极寻找如何在没有ORM的情况下使用Symfony。(我已经实现了DBAL,因为我编写的PDO可以与之一起使用……到目前为止……只需要进行一些小修补)。

让我们开始:

我需要理解的重要概念来自于这个页面:http://symfony.com/doc/current/cookbook/security/custom_provider.html以及关于security.yml文件的所有内容。

关于security文件,我花了一段时间才明白“提供程序”节点只有两个本地选项:“entity”或“memory”。而且,使用“entity”时,人们必须使用ORM。因此,我想出了需要开发自己的提供程序,以便使用常规PDO。

这里是我的一部分代码,以便让你了解我最终是如何使其工作的。下面是以下文件:

  • security.yml(这里可能仍然有改进的空间,因为我还没有深入研究“防火墙”部分的组织);
  • CustomUsersProvider.php:实现UserProviderInterface接口的类(PdoCustom类及其getUser()方法是我自己编写的PDO,用于从我的数据库中检索用户);
  • services.yml:提供对CustomUsersProvider类的访问,并因此在security文件中提供了对“provider”的访问(如果我理解得正确),我将DBAL数据库配置作为参数传递给服务,以便在CustomUsersProvider对象的实例中使用;
  • CustomUsers.php:充当我的表'custom_users'的实体类,以使用PDO::FETCH_CLASS类型的PDO获取;它实现了Symfony接口:UserInterface和EquatableInterface;
  • 您仍然需要实现Symfony控制器SecurityController(在此处找到:http://symfony.com/doc/2.0/book/security.html)及其路由到/login和Twig文件。
  • 阅读代码时,您可能会注意到$ email被用作$ username;

[项目名称]\app\config\security.yml

encoders:
    CustomBundle\Entity\CustomUsers:
       algorithm: [enter an encoding algorithm, eg: MD5, sha512, etc.]

role_hierarchy:
    ROLE_NAME2: ROLE_NAME1
    ROLE_NAME3: ROLE_NAME2

providers:
    custom_users_provider:
        id: custom_users_provider

firewalls:
    main_login:
        pattern: ^/login$
        anonymous: ~
    main:
      pattern: ^/
      anonymous: true
      provider: custom_users_provider
      form_login:
         check_path: /login_check
         login_path: /login
         provider: custom_users_provider
         username_parameter: email
         password_parameter: password

       logout: true

access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/secured_for_role_name, role: ROLE_NAME }

[projectname]\CustomBundle\Security\CustomUsersProvider.php

<?php
namespace CustomBundle\Security;

use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;

use CustomBundle\DependencyInjection\PdoCustom;
use CustomBundle\Entity\CustomUsers;


class CustomUsersProvider implements UserProviderInterface
{
    private $dbalConnection;
    private $logger;

    public function __construct($dbalConnection){
        $this->dbalConnection = $dbalConnection;

        ////////////////EASTER EGG//////////////////////////
        $this->logger = $GLOBALS['kernel']->getContainer()->get('logger');
        $logger->info('EASTER EGG: YOU CAN ADD LOG THAT CAN BE FOUND UNDER [projectname]\var\logs\dev.log WHEN LAUNCHING THRU app_dev.php, WICH COULD BE USEFUL TOO');
        ////////////////////////////////////////////////////
    }


    public function loadUserByUsername($username)
    {
        $PdoCustom = new PdoCustom($this->dbalConnection);
        $userData = $PdoCustom->getUser($username);


        if ($userData) {

            $password = $userData->password;
            $salt = null;
            $role = $userData->role;

            $resToReturn = new CustomUsers();
            $resToReturn->setCharact($username, $password, $role);
            return $resToReturn;
        }

        throw new UsernameNotFoundException(
            sprintf('Username "%s" does not exist.', $username)
        );
    }

    public function refreshUser(UserInterface $user)
    {
        if (!$user instanceof CustomUsers) {
            throw new UnsupportedUserException(
                sprintf('Instances of "%s" are not supported.', get_class($user))
            );
        }
        return $this->loadUserByUsername($user->getUsername());
    }

    public function supportsClass($class)
    {
        return $class === 'CustomBundle\Entity\CustomUsers';
    }
}
?>

[projectname]\src\CustomBundle\Ressources\config\services.yml

custom_bundle.custom_users_provider.class : CustomBundle\Security\CustomUsersProvider

custom_users_provider:
                 class: %custom_bundle.custom_users_provider.class%
                 arguments: ["@doctrine.dbal.default_connection"]

[projectname]\CustomBundle\Entity\CustomUsers.php

  <?php
namespace CustomBundle\Entity;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;

class CustomUsers implements UserInterface, EquatableInterface {

public $email;
public $password;
public $role;

public function __construct(){
}

public function setCharact($email,$password,$role){
    $this->email = $email;
    $this->password = $password;
    $this->status = $status;

}


public function getRoles(){
    return $this->role;

}
public function getPassword(){
    return $this->password;
}
public function getSalt(){
    return null;
}
public function getUsername(){
    return $this->email;
}
public function eraseCredentials(){
}   
public function isEqualTo(UserInterface $user)
{
    if (!$user instanceof CustomUsers) {
        return false;
    }

    if ($this->user_password !== $user->getPassword()) {
        return false;
    }

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

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

    return true;
}
}
?>

就是这样,你仍然需要自己做一些工作来弄清楚所有的内容,但我希望这会给你指引。我之前在寻找如何在没有ORM的情况下使用Symfony时非常困难。


3
你需要做的是插入自己的用户提供者:

http://symfony.com/doc/current/cookbook/security/entity_provider.html

如果您不想使用Doctrine 2对象关系管理器(ORM),可以考虑使用Doctrine 2数据库访问层(DBAL)。这是在PDO之上构建的一个轻量级SQL层。它具有一些用于构建SQL的辅助程序。

http://symfony.com/doc/current/cookbook/doctrine/dbal.html

当然,您可以直接使用PDO:

http://symfony.com/doc/current/cookbook/configuration/pdo_session_storage.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接