Laravel is a tremendously popular web application framework — with good reason! Now in its 10th generation, the framework has built up a robust and mature foundation that’s not just battle-tested but genuinely delightful to build applications with. Laravel has elevated the entire PHP experience to a new level thanks to its incredibly passionate developer community. These days it’s nearly become as synonymous with PHP as Rails has with Ruby. And with PHP running on at least 80% of web servers, that’s a big deal. For a good reason, companies like Disney, Warner Brothers, Twitch, and The New York Times have embraced Laravel.
Auth0 has offered a Laravel SDK for many years — our first release dates back to 2014! A lot has changed since then, and like all our SDKs, we’ve evolved to fit the times and the community’s needs. Every new release is an opportunity to iterate, improve, and create a better developer experience.
Early last year, we released v7 of our Laravel SDK, which was a big one. We rewrote the SDK from the ground up to take advantage of PHP 8 and Laravel 9 and restructured everything on top of our massively upgraded core PHP SDK v8. For the first time, developers could integrate authentication with Auth0 in their Laravel apps in less than ten lines of code, and it was great!
But we wondered — what if you could do it with zero lines of code?
Over the last few months, we’ve been striving to create that experience for our Laravel developers, and as of v7.8 release, we’ve reached that milestone (and so much more).
With Great Power...
Laravel is a robust framework created to support practically any kind of application developers might want to build. It’s one of those rare frameworks that has managed to strike a harmonious balance between powerfully customizable and highly opinionated. And when it comes to something as critical to an application as authentication, if you’re going to tackle the subject, you better be sure you’re striking that same balance successfully. It should “just work” while also being flexible enough to mold to the most niche scenarios.
Admittedly in the past, our Laravel SDK has not always hit that mark on addressing those niches, particularly in supporting monolithic apps; that is, apps that serve JSON APIs with token-based authorization as well as modern frontends with session-based authentication, in the same codebase. The community asked us to create a better solution, but there were some technical hurdles to work through first.
Traditionally, our SDK exposed authentication through a single API, which made integration super simple but meant that, on occasion, developers had to figure out how to support some exotic use cases using just a single SDK configuration. It simply didn’t always work as elegantly as one would hope.
With v7.8, we went back to the drawing board to address this. We took a deep dive into the core of Laravel’s Authentication APIs, drilling into the framework’s source code, and began laying the groundwork for a whole new approach that let us support every type of application (yes, even those tricky monolithic apps!) in exciting new ways. We even learned some new tricks along the way!
Real Artists Ship
Efforts toward these ends began with 7.2, where we started working on the foundation of our new approach. We started by building the support we needed to do this right. We began by releasing support for native Laravel sessions, persistent session storage, and support for Laravel’s native caching APIs. We built experimental Octane support for supercharged applications. We improved reliability by achieving 100% code coverage and implemented mutation testing and triple-filtered static analysis to ensure we caught as many edge cases as possible. We cut a new release each month, bringing us closer to our new goal: a no-code solution that addresses all our customers' requests.
And today, finally, with 7.8, we’ve reached our goal. There’s so much to share, but we’ll distill it down to the headline features:
Changing of the Guard(s)
With 7.8, we released two completely new Guards that leverage every aspect of Laravel’s powerful Authentication API. These new Guards — one for session-based authentication and the other for token-based endpoint authorization — enable support for applications of all types and use cases, finally addressing the demands of those monolithic app developers.
Previously, you had to write the following code:
Route::middleware(['guard:auth0', 'auth0.authenticate'])->get('/messages', function () {
// ...
});
Today you just write as follows:
Route::get('/messages', function () {
//...
} })->middleware('auth');
We created a suite of new middleware and services that support using these Guards without any integration work within the application. There are no editing files, defining middleware, or Kernel changes; it just works. Authentication is immediately available, and any routes configured to use Laravel’s native ‘auth’
middleware for limiting access to authenticated sessions instantly work with Auth0. Zero lines of code!
Previously, you had to define your guards and provider...
// config/auth.config:
return [
'guards' => [
'auth0' => [
'driver' => 'auth0.guard',
'provider' => 'auth0-provider',
]
],
'providers' => [
'auth0-provider' => [
'driver' => 'auth0.provider',
'repository' => \Auth0\Laravel\Auth\User\Repository::class,
]
],
];
...and modify the Kernel:
// app/Http/Kernel.php:
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::Class,
\Illuminate\Routing\Middleware\SubstituteBindings::Class,
\Auth0\Laravel\Auth\Guard::class,
];
}
// routes/web.php:
use Auth0\Laravel\Http\Controllers\{Callback, Login, Logoutl};
Route::group(['middleware' => ['web', 'guard:auth0'], static function (): void {
Route::get('/login', Login::class)->name('login');
Route::get('/logout', Logout::class)->name('logout');
Route::get('/callback', Callback::class)->name('callback');
});
Today, this is all you need to do:
// Nothing! 🎉
And for the first time, we now support Laravel’s powerful native Authorization API, which enables developers to write permissions-based gates and policies that can use Auth0’s RBAC with APIs for fine-grained access control.
This is what you had to write previously:
Route::middleware(['guard:auth0', 'auth0.authenticate'])->group(function () {
Route::get('/messages', function () {
return response("You're authorized to read messages.");
})->can('auth0.authorize:read:messages');
});
Here is what you have to write today:
Route::get('/messages', function () {
return response("You're authorized to read messages.");
})->middleware('auth')->can('read:messages');
Auth0 CLI: First-Class Configuration
To support these new guards, we completely reinvented our SDK configuration API — and ended up building something profoundly flexible and capable. Our new configuration API enables us to support an infinite number of Guard instances in memory at any given time, supporting every conceivable need a developer might have for their application’s authentication needs — which is particularly important for Octane applications.
Our goal with the new configuration API was to simplify the integration experience dramatically, taking a sometimes lengthy explanation process involving application configuration instructions and .env
file editing down to just a few error-proof steps.
What we arrived at was a whole new configuration experience powered by the Auth0 CLI. The CLI is an exciting tool that guides developers in managing their tenants through an elegant command-line interface. It was a perfect fit for simplifying one of the biggest challenges of getting started with the SDK, so we baked in native support for the CLI. Now, the JSON expressed by the CLI can be used to directly configure an application’s Auth0 SDK integration. For the first time, you can configure your tenant and SDK in a single command. It’s pretty awesome!
The Quickest of Quickstarts
We’re always looking for ways to improve a developer’s first experiences with our SDKs, and that all begins with the quickstart. These starter applications demonstrate how a developer can integrate base applications with fully functional authentication as efficiently as possible — ideally resulting in a working app in 5 minutes or less.
Now that we’ve achieved no-code and integrated the Auth0 CLI, developers can do this with their Laravel application in less than a minute.
We re-wrote our Laravel quickstarts from the ground up to showcase this new configuration approach and demonstrate these new features, which cut the length of our quickstart in half. We also reworked the GitHub repository so developers can use it as a starting template for new Laravel applications with a single command.
Want a fully functional Laravel 9 application with Auth0 authentication out of the box? You got it!
composer create-project auth0-samples/laravel
Ready to configure it? Done!
./auth0 apps create \
--name "My Laravel Application" \
--type "regular" \
--auth-method "post" \
--callbacks "http://localhost:8000/callback" \
--logout-urls "http://localhost:8000" \
--reveal-secrets \
--no-input \
--json > .auth0.app.json
You have a ready-to-ship app with completely functional authentication and access control.
Integration Comparison
Let's compare how you would have integrated Auth0 previously with how you do it today.
The old-days integration
Previously, you should have started with the installation:
$ composer global require laravel/installer
$ laravel new example-app
$ cd example-app
$ composer install
$ composer require auth0/laravel
Then, you should have created an application in the Auth0 dashboard...
...and configured it:
Back to your application, you should have configured it with the Auth0 registration data:
AUTH0_DOMAIN="..."
AUTH0_CLIENT_ID="..."
AUTH0_CLIENT_SECRET="..."
AUTH0_COOKIE_SECRET="..."
AUTH0_AUDIENCE="..."
You should have defined your Guards and provider:
// conflg/auth.config:
return [
'guards' => [
'auth0' => [
'driver' => 'auth0.guard',
'provider' => 'auth0-provider',
]
],
'providers' => [
'auth0-provider' => [
'driver' => 'auth0.provider',
'repository' => \Auth0\Laravel\Auth\User\Repository::class,
]
],
];
You should have defined your middleware in the Kernel:
// app/Http/Kernel.php:
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::Class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Auth0\Laravel\Auth\Guard::class,
];
}
You should have added support for authentication...
// routes/web.php:
use Auth0\Laravel\Http\Controllers\fCallback, Login, Logout};
Route::group(['middleware' => ['web', 'guard:auth0'], static function (): void {
Route::get('/login', Login::class)->name('login');
Route::get('/logout', Logout::class)->name('logout');
Route::get('/callback', Callback::class)->name('callback');
});
...and optionally configure the application's routing:
Route:middleware('guard:auth0', 'auth0.authenticatel)->group(function () {
Route::getr('/messages', function () {
return response("You're authorized to read messages.");
})->can('auth0.authorize:read:messages');
});
Today's integration
With the new SDK, you integrate Auth0 in your Laravel application in two easy steps.
First step, create a new application:
$ composer create-project auth0-samples/laravel
Second step, configure your application through the Auth0 CLI:
./auth0 apps create \
--name "My Laravel Application" \
--type "regular" \
--auth-method "post" \
--callbacks "http://localhost:8000/callback" \
--logout-urls"http://localhost:8000"\
--reveal-secrets \
--no-input
--json > .auth0.app.json
Optionally, configure its routing this way:
Route::get('/messages', function () {
return response("You're authorized to read messages.");
})->middleware('auth')->can('readmessages');
Conclusion
At Auth0, we never stop innovating, and our SDKs are absolutely no exception. With v7.8, we’ve achieved a powerful no-code integration, an incredibly streamlined configuration scheme powered by the Auth0 CLI, and we now offer our quickest quickstarts ever. We’re proud of our latest Laravel release, but more importantly, we’re excited to see what developers build with it. We wouldn’t have gotten here without the valuable feedback of our developer community, and we’re excited to continue building the future of authentication in Laravel together.