Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Login with username or email with Cakephp 3

I want to do a login with username or email. So I want to change Auth fields dynamically.

How can I modify $this->Auth fields as Cakehp 2 did?

In cakephp 2 you could do:

$this->Auth->authenticate = array(
    'Form' => array(
        'fields' => array('username' => 'email', 'password' => 'password'),
    ),
);

I've tried to change authenticate like this but it doesn't work:

$this->Auth->config('authenticate', [
    'Form' => [
        'fields' => ['username' => 'email', 'password' => 'password']
    ]
]);

Thanks!

like image 854
aleixfabra Avatar asked Jun 04 '15 16:06

aleixfabra


People also ask

How does CakePHP manage users and user authorization?

In CakePHP this is handled by the AuthComponent , a class responsible for requiring login for certain actions, handling user sign-in and sign-out, and also authorizing logged in users to the actions they are allowed to reach. To add this component to your application open your app/Controller/AppController.


3 Answers

I've found the solution!

I assumed that username is alphaNumeric (letters and numbers).

Remember to add $this->Auth->constructAuthenticate();

AppController.php

use Cake\Controller\Controller;
use Cake\Event\Event;
use Cake\Core\Configure;

class AppController extends Controller
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent('Flash');
        $this->loadComponent('Auth', [
            'loginRedirect' => [
                'controller' => 'Users',
                'action'     => 'index'
            ],
            'logoutRedirect' => [
                'controller' => 'Users',
                'action'     => 'login'
            ]
        ]);
    }
}

UsersController.php

use App\Controller\AppController;
use Cake\Validation\Validation;

class UsersController extends AppController
{
    public function login()
    {
        if ($this->request->is('post')) {

            if (Validation::email($this->request->data['username'])) {
                $this->Auth->config('authenticate', [
                    'Form' => [
                        'fields' => ['username' => 'email']
                    ]
                ]);
                $this->Auth->constructAuthenticate();
                $this->request->data['email'] = $this->request->data['username'];
                unset($this->request->data['username']);
            }

            $user = $this->Auth->identify();

            if ($user) {
                $this->Auth->setUser($user);
                return $this->redirect($this->Auth->redirectUrl());
            }

            $this->Flash->error(__('Invalid username or password, try again'));
        }
    }
}

login.ctp

<div class="form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
    <fieldset>
        <legend><?= __('Please enter your username and password') ?></legend>
        <?= $this->Form->input('username') ?>
        <?= $this->Form->input('password') ?>
    </fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>
like image 58
aleixfabra Avatar answered Oct 10 '22 23:10

aleixfabra


Here is my solution.

AppController.php load Auth component.

$this->loadComponent('Auth', [
        'authorize' => 'Controller',
        'authenticate' => [
            'Form' => [
                'userModel' => 'Users',
            ]
        ],
        ...
    ]);

UsersController.php

Note: identify() method

http://book.cakephp.org/3.0/en/controllers/components/authentication.html#identifying-users-and-logging-them-in

public function login()
{
    if ($this->request->is('post')) {
        //$user = $this->Auth->identify();
        $user = $this->Users->identify($this->request->data);
        if ($user) {
            $this->Auth->setUser($user);
            return $this->redirect($this->Auth->redirectUrl());
        } else {
            $this->Flash->error(__('Username or password is incorrect'), [
                'key' => 'auth'
            ]);
        }
    }
}

UsersTable.php

Assuming that email and username columns are in same table.

use Cake\Auth\DefaultPasswordHasher;

public function identify($formData) {

        $passOk = false;
        $user = $this->find()->hydrate(false)->where(['email' => $formData['email']])->orWhere(['username' => $formData['email']])->first();
        $checker = new DefaultPasswordHasher;
        if(!is_null($passOk))
            $passOk = $checker->check($formData['password'], $user['password']); 

        return $passOk ? $user  : null;

    }
like image 20
I. Degollado Avatar answered Oct 10 '22 22:10

I. Degollado


log in with the username Or Email its Perfect Work just try it.

UsersController.php

    if($this->request->is('post')){
        if(!filter_var($this->request->data['username'], FILTER_VALIDATE_EMAIL)===false){
            $this->Auth->config('authenticate', [
                'Form'=>['fields'=>['username'=>'email', 'password'=>'password']]
            ]);
            $this->Auth->constructAuthenticate();
            $this->request->data['email']=$this->request->data['username'];
            unset($this->request->data['username']);
        }
        pr($this->request->data);

        $user=$this->Auth->identify();
        if($user){
            $this->Auth->setUser($user);
            $this->Flash->success(__('Wel Come-'.ucfirst($user['name'])));
            return $this->redirect($this->Auth->redirectUrl());
        }
        $this->Flash->error(__('Invalid username or password, try again'));
    }
like image 40
Asif vora Avatar answered Oct 10 '22 23:10

Asif vora