Password-less authentication for CakePHP 3
PHP
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
docs
src/Auth
tests
.editorconfig
.gitattributes
.gitignore
.semver
.travis.yml
LICENSE
README.md
VERSION
composer.json
phpunit.xml.dist

README.md

HyperlinkAuth

Build Status Coverage Total Downloads License

Password-less authentication for CakePHP 3.

Send a login hyperlink upon user's email submission on login page.

  1. User submits email
  2. System sends link after validating email
  3. User clicks link
  4. System authenticates user after validating token

Install

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');

Usage

// 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;
}

Patches & Features

  • Fork
  • Mod, fix
  • Test - this is important, so it's not unintentionally broken
  • Commit - do not mess with license, todo, version, etc. (if you do change any, bump them into commits of their own that I can ignore when I pull)
  • Pull request - bonus point for topic branches

To ensure your PRs are considered for upstream, you MUST follow the CakePHP coding standards.

Bugs & Feedback

http://github.com/usemuffin/hyperlinkauth/issues

License

Copyright (c) 2016, Use Muffin and licensed under The MIT License.