Symfony2 authentication (login) without doctrine?

I am new @symfony and completely new in doctrine. The symfony page contains a tutorial on how to create an sf2 login process. And I love it BUT I can't work with doctrine and I don't want to work with it (there are many thinkers who don't work with doctrine ... - like enum's etc.).

How I create a login controller, firewall setup, etc. is explained very well. BUT! I would like to create it without doctrine ... I have an existing database and I love simple sql. :-)

How can I use a simple sql in UserInterface ... that will work with inline input from sf2?

thanks a lot...

+3


source to share


3 answers


What you want to do is hook up your own UserProvider:

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

Instead of the Doctrine 2 Relational Object Manager (ORM), you can use the Doctrine 2 Database Access Layer (DBAL). It is a thin sql layer built on top of PDO. Has some helper procedures for sql creation.



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

Of course, you can just use PDO directly:

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

+3


source


Here is the solution I propose in Symfony 3.0.

When I am implementing an existing postgresql database and I want to reuse a lot of existing PHP code, the ORM is not suitable for my case (too time consuming to reverse engineer). So I was actively looking for how to use Symfony without ORM . (I implemented DBAL because what I wrote for PDO works with it ... so far ... with some minor fixes).

Let's start: An important concept I needed to understand was taken from this page: http://symfony.com/doc/current/cookbook/security/custom_provider.html + everything about the security.yml file.

In the security file, it took me a while to realize that node providers only have two options of their own: "entity" or "memory" . And with "entity" one of them is bound to the ORM . So I realized that I needed to develop my own provider that will work with regular PDO .

Here is some of my code to give you an idea of ​​how I finally did it, you will find the following files below:

  • security.yml (There is probably room for improvement here, since I don't count too much on organizing the firewall part);
  • CustomUsersProvider.php: a class that implements the UserProviderInterface interface (the PdoCustom class and its getUser () method is my own PDO preparation for fetching a user from my DB);
  • services.yml: a service providing access to the CustomUsersProvider class and therefore providing access to the "provider" in the security file (if I checked it incorrectly), I pass the DBAL database configuration as an argument to the service so that it can be used in the instance my CustomUsersProvider object;
  • CustomUsers.php: a class that acts as an object of my "custom_users" table to work with PDO fetching PDO :: FETCH_CLASS; it implements the Symfony interfaces: UserInterface and EquatableInterface;
  • You still need to implement the Symfony Controller SecurityController (find it here: http://symfony.com/doc/2.0/book/security.html ) and its route to the / login and Twig file.
  • You will probably notice when you read the code that $ email is used as $ username;

[project_name] \ application \ 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 }

      



[project_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';
    }
}
?>

      

[project_name] \ 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"]

      

[project_name] \ 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;
}
}
?>

      

So that it is, you still have a job to figure out all of this, but I hope this gives you directions that I find very hard to find on HOW TO USE SYMMETRY WITHOUT ORM :))

+2


source


The Symfony documentation explains everything in the Security chapter. Security

At the beginning of this chapter, all authorization is done without Doctrine.

0


source







All Articles