Password-less authentication for CakePHP 3.
Send a login hyperlink upon user's email submission on login page.
Using Composer:
composer require muffin/hyperlinkauth:1.0.x-dev
You then need to load the plugin. You can use the shell command:
bin/cake plugin load Muffin/HyperlinkAuth
or by manually adding statement shown below to your app's config/bootstrap.php
:
Plugin::load('Muffin/HyperlinkAuth');
// src/Controller/AppController.php
public function initialize()
{
$this->loadComponent('Auth', ['authenticate' => ['Muffin/HyperlinkAuth.Hyperlink']]);
}
And then create your login action:
// src/Controller/UsersController.php
public function login()
{
if (!$this->request->is('post') && !$this->request->is('token')) {
return;
}
$user = $this->Auth->identify();
if ($user === true) {
$this->Flash->success(__('A one-time login URL has been emailed to you'));
return;
}
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Email is incorrect'), [
'key' => 'auth'
]);
}
If you noticed, this is very similar to the default way of doing things, with the difference
that it checks for a token
type of request and handling $user === true
(returned when email
is sent).
For sending the email, there are different approaches you can take. The simplest one (demonstrated
here), uses the UsersController
as the object listening to the Auth.afterIdentify
event. A mailer
would be another way of handling that.
The code:
// src/Controller/UsersController.php
public function implementedEvents()
{
return parent::implementedEvents() + [
'Auth.afterIdentify' => 'afterIdentify',
];
}
public function afterIdentify(Event $event, $result, HyperlinkAuthenticate $auth)
{
if (!$this->request->is('post')) {
return;
}
$token = $auth->token($result);
$url = Router::url($this->Auth->config('loginAction') + ['?' => compact('token')], true);
Email::deliver($result['email'], 'Login link', $url, ['from' => 'no-reply@' . env('HTTP_HOST')]);
return true;
}
To ensure your PRs are considered for upstream, you MUST follow the CakePHP coding standards.
http://github.com/usemuffin/hyperlinkauth/issues
Copyright (c) 2016, Use Muffin and licensed under The MIT License.