CakePHP 3 authentication using the league/oauth2-client.
Using Composer:
composer require muffin/oauth2:dev-master
You then need to load the plugin. You can use the shell command:
bin/cake plugin load Muffin/OAuth2
or by manually adding statement shown below to bootstrap.php
:
Plugin::load('Muffin/OAuth2');
Wait, you're not done yet. This plugin will NOT require any of the clients. You will have to do it yourself:
composer require "league/oauth2-github:^1.0@dev"
First, start by defining the providers:
// either in `config/bootstrap.php`
Configure::write('Muffin/OAuth2', [
'providers' => [
'github' => [
'className' => 'League\OAuth2\Client\Provider\Github',
// all options defined here are passed to the provider's constructor
'options' => [
'clientId' => 'foo',
'clientSecret' => 'bar',
],
'mapFields' => [
'username' => 'login', // maps the app's username to github's login
],
// ... add here the usual AuthComponent configuration if needed like fields, etc.
],
],
]);
// or in `src/Controller/AppController.php`
$this->loadComponent('Auth', [
'authenticate' => [
// ...
'Muffin/OAuth2.OAuth' => [
'providers' => [
// the array from example above
],
],
],
]);
Upon successful authorization, and if the user has no local instance, an event (Muffin/OAuth2.newUser
)
is triggered. Use it to create a user like so:
// bootstrap.php
use Cake\Event\Event;
use Cake\ORM\TableRegistry;
EventManager::instance()->on('Muffin/OAuth2.newUser', [TableRegistry::get('Users'), 'createNewUser']);
// UsersTable.php
use Cake\Event\Event;
use League\OAuth2\Client\Provider\AbstractProvider;
public function createNewUser(Event $event, AbstractProvider $provider, array $data)
{
$entity = $this->newEntity($data);
$this->save($entity);
return $entity->toArray(); // user data to be used in session
}
Finally, once token is received, the Muffin/OAuth2.afterIdentify
event is triggered. Use this to update your local
tokens for example:
// bootstrap.php
use Cake\Event\Event;
use Cake\ORM\TableRegistry;
EventManager::instance()->on('Muffin/OAuth2.afterIdentify', [TableRegistry::get('Tokens'), 'createOrUpdate']);
// TokensTable.php
use Cake\Event\Event;
use League\OAuth2\Client\Provider\AbstractProvider;
public function createOrUpdate(Event $event, AbstractProvider $provider, array $data)
{
// ...
return; // void
}
Next up, you need to create a route that will be used by all providers:
// config/routes.php
Router::connect(
'/oauth/:provider',
['controller' => 'users', 'action' => 'login'],
['provider' => implode('|', array_keys(Configure::read('Muffin/OAuth2.providers')))]
);
Now, if you have already read the book's AuthComponent
documentation, you should be familiar with how to
add the new authentication object to it:
// src/Controller/AppController.php
$this->load('Auth', [
'authenticate' => [
'Form',
'Muffin/OAuth2.OAuth',
]
]);
- 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.
http://github.com/usemuffin/oauth2/issues
Copyright (c) 2015, Use Muffin and licensed under The MIT License.