1
votes

Is it possible to configure CakeDC's Users plugin to use email field as a username?

By default there are both username and email fields in Users plugin and all work great! But I would like to use email as the username for the authentication, so the user registration can be simplified.

I have tried overriding the UsersAuthComponent by loading Auth component in the AppController, but login stops working and says "Wrong username or password".

public function initialize()
{
    parent::initialize();
    $this->loadComponent('Flash');
    $this->loadComponent('Auth', [
        'loginAction' => [
            'plugin' => 'CakeDC/Users',
            'controller' => 'Users',
            'action' => 'login',
        ],
        'authenticate' => [
            'all' => [
                'scope' => ['active' => 1]
            ],
            'CakeDC/Users.RememberMe',
            'Form' => [
                'fields' => ['username' => 'email', 'password' => 'password']
            ]
        ],
        'authorize' => [
            'CakeDC/Users.Superuser',
            'CakeDC/Users.SimpleRbac',
        ],
        'storage' => 'Session'
    ]);

    $this->loadComponent('CakeDC/Users.UsersAuth');
}

Following the documentation, I also turned off the UsersAuthComponent in bootstrap.php.

Configure::write('Users.auth', false);

Is there a trick? I believe it is possible, or maybe a bug?

I am using CakePHP 3.1 and CakeDC User plugin 3.1

2

2 Answers

1
votes

The piece your are possibly missing is to override the login.ctp template to change the form and let the user enter his email.

To do so you need to create a file under: /src/Template/Plugin/CakeDC/Users/Users/login.ctp with the content you would like to have for your login page (usually you'll want to override this page in every app you do) and ensure you create an input "email" in that view. The code could be like this

<div class="users form">
    <?= $this->Flash->render('auth') ?>
    <?= $this->Form->create() ?>
    <fieldset>
        <legend><?= __d('Users', 'Please enter your username and password') ?></legend>
        <?= $this->Form->input('email', ['required' => true]) ?>
        <?= $this->Form->input('password', ['required' => true]) ?>
    </fieldset>
    <?= $this->Form->button(__d('Users', 'Login')); ?>
    <?= $this->Form->end() ?>
</div>

You could use the CakeDC/Users login.ctp template as an example if you want to keep the Social Login links, remember me, etc. I'm using a simplified version of the login form as an example here.

We'll be improving the plugin soon to simplify this override.

0
votes

I think this is what MultiColumnAuthenticate is used for, just viewing the plugin on GitHub. Try something like this:

public function initialize()
{
    parent::initialize();
    $this->loadComponent('Flash');
    $this->loadComponent('Auth', [
        'loginAction' => [
            'plugin' => 'CakeDC/Users',
            'controller' => 'Users',
            'action' => 'login',
        ],
        'authenticate' => [
            'all' => [
                'scope' => ['active' => 1]
            ],
            'CakeDC/Users.RememberMe',
            'FOC/Authenticate.MultiColumn' => [
                'fields' => [
                    'username' => 'username',
                    'password' => 'password'
                ],
                'columns' => ['username', 'email'],
                'userModel' => 'Users',
            ]
        ],
        'authorize' => [
            'CakeDC/Users.Superuser',
            'CakeDC/Users.SimpleRbac',
        ],
        'storage' => 'Session'
    ]);

    $this->loadComponent('CakeDC/Users.UsersAuth');
}

This would check against both email and username when logging in.