Microbe
Microbe

Reputation: 465

Multiple identity properties for authentication in ZF2 with Doctrine 2

I have login form with input text fields:

I have two tables

I have its mapping entities and associations.

But user name not unique within table users, because different groups can include users with equal names. Therefore i need:

  1. find group by name in table groups
  2. find user by name in table users with condition where group_id=<group_id>

How to do it correctly in Zend Framework 2 using Doctrine 2? All official documentation and examples depict situation, where identity property is single column (example).

Sorry for my bad language. Thanks.

Upvotes: 1

Views: 972

Answers (2)

Microbe
Microbe

Reputation: 465

Instead of making my own implementation of Doctrine's authentication services i decide to implement it via form validation inside isValid() method of my authentication form.

Example:

<?php

namespace My\Form\Namespace;

use Zend\Form\Form;
use Zend\ServiceManager\ServiceLocatorInterface;
use Zend\InputFilter\InputFilterProviderInterface;

class Auth extends Form implement InputFilterProviderInterface
{
    protected $_em;

    public function __construct(ServiceLocatorInterface $sm)
    {
        parent::__construct('auth');

        // inject Doctrine's Entity Manager
        $this->_em = $sm->get('Doctrine\ORM\EntityManager');

        // login field
        $this->add(...);

        // password field
        $this->add(...);

        // group_name field
        $this->add(...);
    }

    public function getInputFilterSpecification()
    {
        //Input filter specification here
        ...
    }

    public function isValid()
    {
        /*
         * input filter validations
         */
        if (!parent::isValid())
            return false;

        /*
         * group exists validation
         */
        $group = $this->_em
            ->getRepository('<Group\Entity\Namespace>')
            ->findOneBy(array(
                'name' => $this->get('group_name')->getValue(),
            ));
        if (!$group){
            $this->get('group_name')
                ->setMessages(array(
                    'Group not found',
                ));
            return false;
        }

        /*
         * user exists validation
         */
        $user = $this->_em
            ->getRepository('<User\Entity\Namespace>')
            ->findOneBy(array(
                'group_id' => $group->getId(),
                'name' => $this->get('login')->getValue(),
            ));
        if (!$user){
            /*
             * It's not good idea to tell that user not found,
             * so let it be password error
             */
            $this->get('password')
                ->setMessages(array(
                    'Login or password wrong',
                ));
            return false;
        }

        /*
         * password validation
         */
        $password = $this->get('password')->getValue();
        // assume that password hash just md5 of password string
        if (md5($password) !== $user->getPassword()){
            $this->get('password')
                ->setMessages(array(
                    'Login or password wrong',
                ));
            return false;
        }

        return true;
    }
}

Inside controller it is enough to call $form->isValid() to make sure that user entered correct authentication data.

Upvotes: 1

herinson
herinson

Reputation: 11

I have the same problem.

I have to do two authentications in same application, because my boss doesn't wanna two databases. So, I had to make two user tables and two login pages.

One route to admin -> /admin/login And the front-end for other users -> /login

I've tried to put on more authenticate in doctrine authentication array but it didn't work.

I think I'll open a issue on doctrine github page.

Upvotes: 0

Related Questions