OAuth

Pro Feature

Overview

Statamic supports OAuth authentication via Laravel Socialite, which includes support for Facebook, Twitter, Google, LinkedIn, GitHub, and Bitbucket.

The Socialite Providers Github organization contains over 100 additional pre-built providers that you can take advantage of as well.

If you require a provider not on the list, (perhaps you need a custom one for your own application) you may create your own provider.

Installing Socialite

Install Socialite with the following Composer command:

composer require laravel/socialite

Enable OAuth in config/statamic/oauth.php or in your environment file:

STATAMIC_OAUTH_ENABLED=true

Add the provider to the oauth config. This will allow Statamic to add buttons to the CP login form.

'providers' => [
'github',
],

Add your provider's credentials to config/services.php and callback URL as per the Socialite documentation:

'github' => [
'client_id' => env('GITHUB_CLIENT_ID'),
'client_secret' => env('GITHUB_CLIENT_SECRET'),
'redirect' => 'http://your-site.com/oauth/github/callback',
],

If you plan to use a third party provider, follow the steps below.

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:github }}">Log in with Github</a>

Once they've logged in at their provider's site, they will be redirected back to your site where a Statamic user account will either be retrieved or created.
They will then be automatically logged into your site with the Statamic account.

You may customize how the user is created.

Configuration

OAuth behavior may be configured in config/statamic/oauth.php.

Providers

You should add your intended OAuth providers to the config so Statamic can provide your users with buttons on the login page.

You can specify just the name of the provider, or use a name/label pair if you would like to customize how it's displayed.

'providers' => [
'facebook',
'github' => 'GitHub',
'twitter',
],

If a provider requires "stateless authentication", you may pass an array and specify the stateless config option:

'providers' => [
'saml2' => ['stateless' => true, 'label' => 'Okta'],
],

Routes

There are 2 required routes in order for the OAuth workflow to function:

  • A login redirect route, which sends users to the provider's login page.
  • A callback route, which the provider will redirect to after a successful login.

You may customize these in config/statamic/oauth.php:

'routes' => [
'login' => 'oauth/{provider}',
'callback' => 'oauth/{provider}/callback'
],

When you create your OAuth application, you will need to provide the callback URL.

Third Party Providers

If you would like to use a provider not natively supported by Socialite, you should use the SocialiteProviders method.

  1. Require the appropriate provider using Composer:

    composer require socialiteproviders/dropbox
  2. Next, add an event listener in your AppServiceProvider's boot method:

    // app/Providers/AppServiceProvider.php
     
    Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
    $event->extendSocialite('dropbox', \SocialiteProviders\Dropbox\Provider::class);
    });

    Alternatively, if your application has an EventServiceProvider.php file, you can register the event listener in there:

    protected $listen = [
    \SocialiteProviders\Manager\SocialiteWasCalled::class => [
    'SocialiteProviders\\Dropbox\\DropboxExtendSocialite@handle',
    ],
    ];
  3. Add the service credentials to config/services.php config:

    'dropbox' => [
    'client_id' => env('DROPBOX_CLIENT_ID'),
    'client_secret' => env('DROPBOX_CLIENT_SECRET'),
    'redirect' => 'http://your-site.com/oauth/dropbox/callback',
    ],
  4. Add the provider to the config/statamic/oauth.php config:

    'providers' => [
    'dropbox',
    ],

Custom Providers

If your OAuth provider isn’t already available in Socialite or SocialiteProviders, you may create your own.

To create your own OAuth provider, you should make your own SocialiteProvider-ready provider. All that's needed is the event handler (eg. DropboxExtendSocialite.php) and the provider (eg. Dropbox.php).

Follow the third party installation steps, but skip the Composer bits. You can just keep the classes somewhere in your project.

Customizing User Data

After authenticating with the provider, Statamic will try to retrieve the corresponding user, or create one if it doesn't exist. You may customize how it's handled by adding a callback to your AppServiceProvider.

User data

The only data added to the user will be their name. If you would like to customize what gets added to the user, you can return an array from the provider's withUserData callback.

The closure will be given:

  • an instance of Laravel\Socialite\Contracts\User
  • the existing Statamic\Contracts\Auth\User if one already exists.
use Statamic\Facades\OAuth;
 
OAuth::provider('github')
->withUserData(fn ($socialiteUser, $statamicUser) => [
'name' => $socialiteUser->getName(),
'created_at' => optional($statamicUser)->created_at
?? now()->format('Y-m-d'),
]);
Warning!

This user data will get merged into the user every time they log in using OAuth. This includes if they had an existing non-OAuth user account.

Customize entire user creation

If you want more control over the actual user object being created, you can return a user from the provider's withUser callback. The closure will be given an instance of Laravel\Socialite\Contracts\User.

use Statamic\Facades\User;
use Statamic\Facades\OAuth;
 
OAuth::provider('github')->withUser(function ($user) {
return User::make()
->email($user->getEmail())
->set('name', $user->getName());
});
Warning!

This will only be used when the user is initially created. If you'd like to also update the data on every login, you should combine this with the withUserData option above.

public function boot()
{
OAuth::provider('github')
->withUserData(fn ($user) => $this->userData($user))
->withUser(function ($user) {
return User::make()
->email($user->getEmail())
->data($this->userData($user));
});
}
 
private function userData($user)
{
return [
'name' => $user->getName(),
];
}

HR: Section
Learn More!

There is more to learn more in these related articles:

Docs

HR: Section
Docs feedback

Submit improvements, related content, or suggestions through Github.

Betterify this page →