Symfony2无原则身份验证(登录)


Symfony2 Authentication (Login) without Doctrine?

我是新来的@symfony,对学说绝对陌生。symfony页面上有一个关于在sf2中构建登录过程的教程。我喜欢它,但我不能用教条,我也不想用它(有很多想法不适用于教条……例如enum等)。

我如何创建一个登录控制器,防火墙设置,等等。解释得很好。但是!我想在没有教条的情况下创造它。。。我有一个现有的数据库,我喜欢纯sql。:-)

如何在UserInterface中使用纯sql。。。这将适用于sf2的内置登录?

太多了。。。

您想要做的是插入您自己的UserProvider:

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

代替条令2对象关系管理器(ORM),您可以考虑使用条令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

这是我在Symfony 3.0上提出的一个解决方案。

由于我实现了一个现有的postgresql数据库,并且我想重用很多已经存在的PHP代码,ORM不适合我的情况(做反向工程的时间成本太高)。因此,我一直在积极探索如何在没有ORM的情况下使用Symfony。(我确实实现了DBAL,因为我为PDO编写的内容与之配合……到目前为止……还有一些小的修复)。

让我们开始:我需要理解的重要概念摘自本页:http://symfony.com/doc/current/cookbook/security/custom_provider.html+关于security.yml文件的所有内容。

关于安全文件,我花了一段时间才明白节点"providers"只有两个本机选项:"entity"或"memory"。对于"实体",一个必然与ORM一起工作。因此,我发现我需要开发自己的提供商,以便与常规PDO一起工作。

下面是我的一些代码,让你了解我是如何最终实现它的,你会在下面找到以下文件:

  • security.yml(这里可能还有一些改进的空间,因为我还没有过多地挖掘"防火墙"部分组织)
  • CustomUsersProvider.php:实现接口的类UserProviderInterface(类PdoCustom及其方法getUser()是我自己的PDO烹饪,用于从我的DB中检索用户)
  • services.yml:该服务提供对类CustomUsersProvider的访问权限,从而提供对安全文件中"provider"的访问权限(如果我正确地解析了它),我将DBAL数据库配置作为服务中的参数传递,以便它可以在我的对象CustomUsersProver的实例中使用
  • CustomUsers.php:充当我的表的实体的类"custom_users",以使用PDO::FETCH_CLASS类型的PDO获取;实现了Symfony接口:UserInterface和EquatableInterface
  • 您仍然需要实现Symfony Controller 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 }

[项目名称]''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';
    }
}
?>

[项目名称]''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"]

[项目名称]''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的情况下使用符号上很难找到:)