0
votes

I am working with zend 2 authentication. Now there is a case that a user can login with a user name and password or email and password. Is it possible to give both username and email as identity in zend 2. Otherwise how can i manage the situation?

This is my current working code. Here am using email as identity and password as credential.

in Module.php

public function getServiceConfig()
{
    return array(
        'factories' => array(

            'AuthService' => function($sm) {
                $dbTableAuthAdapter     = new DbTableAuthAdapter(
                    $sm->get('Zend\Db\Adapter\Adapter'),
                    'users',
                    'email',
                    'password'
                );
                $authService            = new AuthenticationService();
                $authService->setAdapter($dbTableAuthAdapter);
                return $authService;
            },

        )
    );
}

and in controller,

  $this->getAuthService()->getAdapter()->setIdentity($oRequest->getPost('username'))->setCredential(md5($oRequest->getPost('password')));
            $select      = $this->getAuthService()->getAdapter()->getDbSelect();
            $select->where('is_active = 1');

            $oResult     = $this->getAuthService()->authenticate();

            // Authentication ends here 

            if ($oResult->isValid()) {
        // code after authentication
    }

Any ideas? Thank you.

2
This would certainly require a custom Authentication Adapter class, perhaps extending Zend\Authentication\Adapter\DbTable\AbstractAdapter. You could modify the 'identity column' to be an array of valid column names and use these when building the select query in authenticateCreateSelect.AlexP

2 Answers

1
votes

If you're using Zend\Authentication\Adapter\DbTable adapter, perhaps you could try something like this:

        $this->getAuthService()->getAdapter()
          ->setIdentity($oRequest->getPost('username'))
          ->setCredential(md5($oRequest->getPost('password')));
        $select  = $this->getAuthService()->getAdapter()->getDbSelect();
        $select->where('is_active = 1');

        $oResult = $this->getAuthService()->authenticate();

        if (!$oResult->isValid()) { //authentication by username failed, try with email
            $this->getAuthService()->getAdapter()->setIdentityColumn('email')
              ->setIdentity($oRequest->getPost('email'))
              ->setCredential(md5($oRequest->getPost('password')));

            $oResult = $this->getAuthService()->authenticate();
        }
        return $oResult->isValid();
0
votes

Another way could be to create 2 authentication services, one for email and another for username.

When a user submits a login check if its a valid email. In this case, use the email authentication service. Otherwise, choose the username authentication service.

You can check if its a valid email with zend email validator as from Zend website

$validator = new Zend\Validator\EmailAddress();
if ($validator->isValid($login)) {
     // email appears to be valid
     // Use email authentication service
} else {
     // email is invalid; It may be the username.
     // use username authentication service
}