OAuth
As of Statamic 2.1, authenticating with OAuth is supported with the help of Laravel Socialite and a simple bridge addon
Overview
Out of the box, Statamic supports the providers that are bundled with Socialite (Facebook, Twitter, Google, LinkedIn, GitHub, and Bitbucket).
The Socialite Providers Github organization contains a large number of additional providers (91 at the time of writing) that require minimal effort to install.
Finally, if you require a provider that isn’t on that list, you may write your own, which is also quite straight forward. Here’s how.
Setup
Install the OAuth Bridge addon files. You can find them below.
If using any third party providers from SocialiteProviders, add their composer package to the require
array in OAuthBridge’s composer.json
file. These are normally in the format "socialiteproviders/dropbox": "^2.0"
. Then run php please update:addons
to install it.
Add the providers to the OAuthBridgeServiceProvider
’s $oauth_providers
array with the name of the provider as the key, and the event listener as the value. If you are using a provider that comes with Socialite (Facebook, Twitter, Google, LinkedIn, GitHub and Bitbucket), the listener can be null
.
OAuthBridge addon files
site/addons/OAuthBridge/composer.json
{
"name": "statamic/oauth-bridge",
"require": {
}
}
site/addons/OAuthBridge/OAuthBridgeServiceProvider.php
<?php
namespace Statamic\Addons\OAuthBridge;
use Statamic\Providers\OAuthServiceProvider as ServiceProvider;
class OAuthBridgeServiceProvider extends ServiceProvider
{
/**
* An array of OAuth providers and their listeners
*
* @var array
*/
protected $oauth_providers = [
// Built-in providers can be null.
// 'facebook' => null,
// SocialiteProviders use the event class documented on their site.
// 'dropbox' => 'SocialiteProviders\Dropbox\DropboxExtendSocialite'
];
}
Configuring OAuth
Create an application
Create an OAuth application on the service of your choice. Take note of the client and secret keys.
When they ask for a “callback URL” or “redirect URL”, you should provide http://your-site.com/oauth/{provider}/callback
, where {provider}
would be github
, facebook
, etc.
Add your credentials to Statamic
The Socialite docs will instruct you to add your credentials to services.php
. Instead, add your OAuth credentials to site/settings/services.yaml
in the format of:
dropbox:
client_id:
client_secret:
github:
client_id:
client_secret:
Statamic will put these in the right place behind the scenes.
You can use environment variables here by doing client_id: '{env:GITHUB_CLIENT_ID}'
, etc.
Other Socialite documentation will normally instruct you to add redirect
keys to each service. You can leave these out, Statamic will automatically set them to http://your-site.com/oauth/{provider}/callback
. for you
Routing
Out of the box, the oauth route will be located at /oauth/*
. You can change that by adding the following to your OAuthBridgeServiceProvider
:
public static $oauth_route = 'foo/bar';
This will change the routes to /foo/bar/*
.
Redirect
By default, once you log in with OAuth, you will be redirected to the homepage. You may override this behavior
by adding a redirect
query parameter. This can be added with a parameter on the oauth tag.
Usage
Send your users to the provider’s login URL to begin the OAuth workflow. You may do this with the oauth
tag.
<a href="{{ oauth:login_url provider='github' }}">Log in with Github</a>
or the shorthand:
<a href="{{ oauth:github }}">Log in with Github</a>
Read more about the OAuth Tag.
Customization
By default, when someone authenticates with a service, Statamic will look for an existing user that is assigned the corresponding OAuth ID, and log in as them. If no matching user is found, a user will be created with an automated username.
User creation
You may override the whole user creation logic by listening for Statamic\Events\OAuth\FindingUser
. You may perform whatever logic you need, as long as you return an instance of a Statamic\Contracts\Users\User
.
If you return anything else, Statamic will continue with its default workflow.
Example:
public $events = [
'Statamic\Events\OAuth\FindingUser' => 'findUser'
];
public function findUser(FindingUser $event)
{
if ($event->provider !== 'provider_we_are_interested_in_handling') {
return; // Returning nothing will make Statamic continue as per usual.
}
// create a user ...
return $user;
}
By listening for this event and providing a user, you are in control of all the logic.
Username creation
If you don’t need to control all the user find/create logic, but would like to customize the username, you may listen for the Statamic\Events\OAuth\GeneratingUsername
event and then return a string.
Example:
public $events = [
'Statamic\Events\OAuth\GeneratingUsername' => 'username'
];
public function username(GeneratingUsername $event)
{
return 'a-custom-username';
}
By default, Statamic will generate a username by slugifying the email address and appending a timestamp.
User data creation
Like the username creation, you may also just specify the data to be saved to the user.
Listen for the Statamic\Events\OAuth\GeneratingUserData
event and return an array.
Example:
public $events = [
'Statamic\Events\OAuth\GeneratingUserData' => 'userData'
];
public function userData(GeneratingUserData $event)
{
return ['foo' => 'bar'];
}
Custom Providers
If your OAuth provider isn’t already available, you may create your own provider.
Before you dive into creating your own, you should check the SocialiteProviders site, there’s close to 100 providers ready for you to drop in.
To create a provider, you’ll basically be following the documentation on the SocialiteProviders Contribute page with a couple of things relocated for Statamic.
We’ll be creating a provider that authenticates with the Bacon service. Wouldn’t it be nice to authenticate with bacon?
First up, you’ll need to create the Provider
class as per their docs. This is the class that Socialite uses to
communicate with the OAuth server. Here’s a little boilerplate:
site/addons/BaconOAuth/Provider.php
<?php
namespace Statamic\Addons\BaconOAuth;
use Laravel\Socialite\Two\ProviderInterface;
use SocialiteProviders\Manager\OAuth2\AbstractProvider;
class Provider extends AbstractProvider implements ProviderInterface
{
// implement the methods from the provider interface
}
Next is the event handler. Again, it’s just like the examples from their docs. Make sure you point to wherever you placed
the Provider.php
class.
site/addons/BaconOAuth/BaconExtendSocialite.php
<?php
namespace Statamic\Addons\BaconOAuth;
use SocialiteProviders\Manager\SocialiteWasCalled;
class BaconExtendSocialite
{
/**
* Register the provider.
*
* @param \SocialiteProviders\Manager\SocialiteWasCalled $socialiteWasCalled
*/
public function handle(SocialiteWasCalled $socialiteWasCalled)
{
$socialiteWasCalled->extendSocialite(
'bacon', // the key you will use in the event listener
'Statamic\Addons\BaconOAuth\Provider'
);
}
}
That’s it! Make sure to add your provider to the Bridge addon’s $oauth_providers
array. You’ll use the key you
defined in the event handler class, and the event will be the event handler’s class.
protected $oauth_providers = [
'bacon' => 'Statamic\Addons\BaconOAuth\BaconExtendSocialite'
];