views:

79

answers:

1

So I am using Zend_Auth to authenticate users of my website. Currently they are only able to log in with their email as login but I would like to enable them to log in also with their username.

Here is some code:

        // prepare adapter for Zend_Auth
        $adapter = new Zend_Auth_Adapter_DbTable($this->_getDb());
        $adapter->setTableName('users');
        $adapter->setIdentityColumn('email');
        $adapter->setCredentialColumn('password_hash');
        $adapter->setCredentialTreatment('CONCAT(SUBSTRING(password_hash, 1, 40), SHA1(CONCAT(SUBSTRING(password_hash, 1, 40), ?)))');
        $adapter->setIdentity($request->getParam('email'));
        $adapter->setCredential($request->getParam('password'));

Notice the line:

        $adapter->setIdentityColumn('email');

How can I add also username there (column in the database called username, too)?

UPDATE:

This is how I solved this:

        $login = $request->getParam('email');
        $validator = new Zend_Validate_EmailAddress();
        if (false === $validator->isValid($login)) {
            $u = $this->_getTable('Users')->getSingleWithUsername($login);
            if (null === $u) {
                throw new Exception ('Invalid login and/or password');
            }
            $login = $u->email;
        }

        // prepare adapter for Zend_Auth
        $adapter = new Zend_Auth_Adapter_DbTable($this->_getDb());
        $adapter->setTableName('users');
        $adapter->setIdentityColumn('email');
        $adapter->setCredentialColumn('password_hash');
        $adapter->setCredentialTreatment('CONCAT(SUBSTRING(password_hash, 1, 40), SHA1(CONCAT(SUBSTRING(password_hash, 1, 40), ?)))');
        $adapter->setIdentity($login);
        $adapter->setCredential($request->getParam('password'));
+2  A: 

I deal with the same thing, and I handle it before Zend_Auth. I use a single user sign-in field and first check whether it's an email address -- if so, it's converted to the appropriate username. Then, let Zend_Auth do its thing.

This works well for me, although you'll need to kinda switch it around, since you're going the other way.


i. Add a filter to your user sign-in field, like this:

$user_field->addFilter('EmailToUsername');


ii. The filter:

<?php

/**
 * Converts an email address to the username.
 */
class Prontiso_Filter_EmailToUsername implements Zend_Filter_Interface
{
  public function filter( $value )
  {
    if ( Zend_Validate::is($value, 'EmailAddress') ) {

      $user_table = new Users();
      $user = $user_table->findByEmail($value);
      if ( $user ) {
        return $user->username;
      }
    }

    /**
     * Nothing happened, so don't filter.
     */
    return $value;
  }
}


As for just changing a Zend_Auth setting instead, Zend_Auth doesn't like either/or identity columns, so you'd have to write your own auth adapter.

Derek Illchuk
I have solved it by using the email adress validator in the controller instead in the form. Check out my updated post. I don't like creating custom filters and such and this works as well.
Richard Knop