auth0-laravel
>
Works with
---
name: auth0-laravel
description: >
license: Apache-2.0
---
# Auth0 Laravel Web App Integration
Add login, logout, and user profile to a Laravel web application using `auth0/login` (Laravel Auth0 SDK).
---
## Prerequisites
- Laravel 11+ application
- PHP 8.2+ with extensions: `mbstring`, `openssl`, `json`
- Composer installed
- Auth0 Regular Web Application configured (not an API - must be an Application)
- If you don't have Auth0 set up yet, use the `auth0-quickstart` skill first
## When NOT to Use
| Scenario | Use Instead |
|----------|-------------|
| Laravel API with JWT Bearer validation | `auth0-laravel-api` (stateless token guard) |
| Plain PHP (no framework) web app | `auth0-php` |
| Plain PHP API | `auth0-php-api` |
| Single Page Applications | `auth0-react`, `auth0-vue`, or `auth0-angular` |
| Next.js applications | `auth0-nextjs` |
| Node.js web apps | `auth0-express` or `auth0-fastify` |
| Flask web apps | `auth0-flask` |
---
## Quick Start Workflow
### 1. Install SDK
```bash
composer require auth0/login
```
The `auth0/login` package requires `auth0/auth0-php` (v8.19+) and will install it automatically. It also requires a PSR-18 HTTP client - if you don't already have one, install Guzzle:
```bash
composer require guzzlehttp/guzzle guzzlehttp/psr7
```
### 2. Publish Configuration
```bash
php artisan vendor:publish --tag=auth0
```
This creates `config/auth0.php` with guard, middleware, and route configuration.
### 3. Configure Environment
Add to your `.env`:
```bash
APP_URL=http://localhost:8000
AUTH0_DOMAIN=your-tenant.us.auth0.com
AUTH0_CLIENT_ID=your_client_id
AUTH0_CLIENT_SECRET=your_client_secret
AUTH0_AUDIENCE=https://your-api-identifier
AUTH0_REDIRECT_URI=${APP_URL}/callback
```
`AUTH0_DOMAIN` is your Auth0 tenant domain (without `https://`). `AUTH0_CLIENT_ID` and `AUTH0_CLIENT_SECRET` come from your Auth0 Application settings. `AUTH0_AUDIENCE` must be set to an API identifier registered in Auth0 (Auth0 Dashboard > Applications > APIs) - without it, Auth0 returns opaque access tokens that the SDK cannot decode, causing a crash on session restore. The SDK uses `APP_KEY` as the cookie secret by default - no separate secret needed.
**Important:** Ensure `APP_URL` includes the port if using the built-in dev server (`http://localhost:8000`). Fresh Laravel installs default to `http://localhost` (no port) which causes callback URL mismatches.
### 4. Configure Auth0 Dashboard
In your Auth0 Application settings:
- **Application Type**: Regular Web Application
- **Allowed Callback URLs**: `http://localhost:8000/callback`
- **Allowed Logout URLs**: `http://localhost:8000`
### 5. Configure Auth Guards
Update `config/auth.php` to use Auth0 guards:
```php
'guards' => [
'web' => [
'driver' => 'auth0.authenticator',
'provider' => 'auth0-provider',
'configuration' => 'web',
],
],
'providers' => [
'auth0-provider' => [
'driver' => 'auth0.provider',
'repository' => 'auth0.repository',
],
],
```
The `configuration` key maps to the guard definition in `config/auth0.php` (`web` uses `STRATEGY_REGULAR` with session-based auth). We override the default `web` guard so that Laravel's built-in `auth` middleware and `auth()->user()` work without specifying a guard name. The SDK also auto-registers an `auth0-session` guard with identical config, but overriding `web` is simpler.
### 6. Routes Are Auto-Registered
The SDK automatically registers these routes when `registerAuthenticationRoutes` is `true` in `config/auth0.php`:
- `GET /login` - Redirects to Auth0 Universal Login
- `GET /callback` - Handles OAuth callback, exchanges code for tokens
- `GET /logout` - Destroys session and redirects to Auth0 logout
No manual route definitions needed for the auth flow.
### 7. Add Protected Routes
In `routes/web.php`:
```php
use Illuminate\Support\Facades\Route;
Route::get('/', function () {
return view('home', ['user' => auth()->user()]);
});
Route::middleware('auth')->group(function () {
Route::get('/profile', function () {
return view('profile', ['user' => auth()->user()]);
});
});
```
The standard `auth` middleware works with the Auth0 guard. Unauthenticated users are redirected to `/login`.
### 8. Create Views
Create `resources/views/home.blade.php`:
```blade
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
</head>
<body>
@if($user)
<h1>Welcome, {{ $user->name }}!</h1>
<p><a href="/profile">Profile</a></p>
<p><a href="/logout">Logout</a></p>
@else
<h1>Welcome</h1>
<p><a href="/login">Login</a></p>
@endif
</body>
</html>
```
Create `resources/views/profile.blade.php`:
```blade
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profile</title>
</head>
<body>
<h1>{{ $user->name }}</h1>
<p>Email: {{ $user->email }}</p>
<img src="{{ $user->picture }}" alt="avatar" width="100" />
<hr>
<h2>User Claims</h2>
<pre>{{ json_encode($user->jsonSerialize(), JSON_PRETTY_PRINT) }}</pre>
<p><a href="/">Home</a> | <a href="/logout">Logout</a></p>
</body>
</html>
```
### 9. Test Authentication
```bash
php artisan serve
```
Visit `http://localhost:8000` and click Login.
**Important:** Always access the app via `http://localhost:8000` (not `http://127.0.0.1:8000`). The callback URL uses `localhost`, so the session cookie must be set for `localhost` to persist across the Auth0 login redirect. Using `127.0.0.1` causes an "Invalid state" error because the session cookie won't be sent to the `localhost` callback URL.
---
## Common Mistakes
| Mistake | Fix |
|---------|-----|
| Using `auth0/auth0-php` directly in Laravel | Use `auth0/login` which wraps the SDK with Laravel guards, middleware, and routes |
| App created as SPA type in Auth0 Dashboard | Must be Regular Web Application for server-side session auth |
| Missing callback URL in Auth0 Dashboard | Add `http://localhost:8000/callback` to Allowed Callback URLs |
| Missing logout URL in Auth0 Dashboard | Add `http://localhost:8000` to Allowed Logout URLs |
| Not publishing the config | Run `php artisan vendor:publish --tag=auth0` before configuring |
| Using wrong guard driver name | Driver is `auth0.authenticator` (not `auth0` or `auth0.guard`) |
| Forgetting to set `APP_KEY` | Run `php artisan key:generate` - the SDK uses this as cookie secret |
| Calling `Auth0::getCredentials()` directly | Use Laravel's `auth()->user()` - the SDK integrates via guards |
| Manually defining `/login`, `/callback`, `/logout` routes | Routes are auto-registered by the service provider |
| Setting `AUTH0_DOMAIN` with `https://` prefix | Use bare domain: `tenant.us.auth0.com` not `https://tenant.us.auth0.com` |
| Using `$request->user()` without middleware | Only available in routes with the `auth` middleware applied |
| Missing `AUTH0_AUDIENCE` env var | Without an audience, Auth0 returns opaque tokens the SDK cannot parse - causes "JWT string must contain two dots" crash |
| Visiting `http://127.0.0.1:8000` instead of `http://localhost:8000` | Session cookies set for `127.0.0.1` won't be sent to the `localhost` callback - causes "Invalid state" error |
| Using `$user->getName()` or `$user->getEmail()` | `StatefulUser` uses magic `__get` - use `$user->name`, `$user->email`, `$user->picture` |
---
## Key SDK Methods
| Method | Usage | Purpose |
|--------|-------|---------|
| `auth()->user()` | In routes/controllers | Returns the authenticated `StatefulUser` or `null` |
| `auth()->check()` | In routes/controllers/views | Returns `true` if user is authenticated |
| `auth()->guard('web')` | When using multiple guards | Gets a specific Auth0 guard instance |
| `$user->name` | On user object | User's display name (via `__get` magic) |
| `$user->email` | On user object | User's email (via `__get` magic) |
| `$user->picture` | On user object | User's avatar URL (via `__get` magic) |
| `$user->getAuthIdentifier()` | On user object | Returns the Auth0 `sub` claim |
| `$user->getAttribute('claim')` | On user object | Returns any claim value explicitly |
| `$user->jsonSerialize()` | On user object | Returns all user claims as array |
---
## User Object
The authenticated user is a `StatefulUser` instance implementing Laravel's `Authenticatable` contract. It uses `__get` magic for property-style access to claims:
```php
$user = auth()->user();
$user->name; // display name (via __get)
$user->email; // email address (via __get)
$user->picture; // avatar URL (via __get)
$user->email_verified; // any claim via property access
$user->getAuthIdentifier(); // Auth0 'sub' (e.g. 'auth0|abc123')
$user->getAttribute('sub'); // explicit claim access
$user->jsonSerialize(); // all claims as array
```
Access any ID token claim as a property: `$user->nickname`, `$user->updated_at`, `$user->sub`, etc. For explicit access, use `$user->getAttribute('claim_name')`.
---
## Related Skills
- `auth0-laravel-api` - Protect Laravel API routes with JWT Bearer token validation
- `auth0-php` - Plain PHP web apps without a framework
- `auth0-quickstart` - Initial Auth0 setup
- `auth0-mfa` - Add Multi-Factor Authentication
- `auth0-cli` - Manage Auth0 resources from the terminal
---
## Quick Reference
**Guard configuration (`config/auth.php`):**
```php
'guards' => [
'web' => [
'driver' => 'auth0.authenticator',
'provider' => 'auth0-provider',
'configuration' => 'web',
],
],
'providers' => [
'auth0-provider' => [
'driver' => 'auth0.provider',
'repository' => 'auth0.repository',
],
],
```
**Route protection:**
```php
Route::middleware('auth')->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index']);
});
```
**Check auth in Blade:**
```blade
@auth
<p>Hello, {{ auth()->user()->name }}</p>
@else
<a href="/login">Login</a>
@endauth
```
**Environment variables:**
- `APP_URL` - Application URL with port (e.g. `http://localhost:8000`)
- `AUTH0_DOMAIN` - Auth0 tenant domain (e.g. `tenant.us.auth0.com`)
- `AUTH0_CLIENT_ID` - Application client ID
- `AUTH0_CLIENT_SECRET` - Application client secret
- `AUTH0_AUDIENCE` - API identifier (required for JWT access tokens)
- `AUTH0_REDIRECT_URI` - Callback URL (defaults to `${APP_URL}/callback`)
- `APP_KEY` - Laravel app key, used as cookie encryption secret
---
## Detailed Documentation
- **[Setup Guide](references/setup.md)** - Automated setup scripts, environment configuration, Auth0 CLI usage
- **[Integration Guide](references/integration.md)** - Scope checking, calling APIs, events, custom user models, session management
- **[API Reference](references/api.md)** - Complete guard API, configuration options, user model methods
---
## References
- [Auth0 Laravel Quickstart](https://auth0.com/docs/quickstart/webapp/laravel)
- [SDK GitHub Repository](https://github.com/auth0/laravel-auth0)
- [SDK on Packagist](https://packagist.org/packages/auth0/login)More Backend Frameworks skills
git-guardrails-claude-code
mattpocock/skills
Set up Claude Code hooks to block dangerous git commands (push, reset --hard, clean, branch -D, etc.) before they execute. Use when user wants to prevent destructive git operations, add git safety hooks, or block git push/reset in Claude Code.
azure-compute
microsoft/azure-skills
Azure VM/VMSS router. WHEN: create / provision / deploy / spin-up VM, recommend VM size, compare VM pricing, VMSS, scale set, autoscale, burstable, lightweight server, website, backend, GPU, machine learning, HPC simulation, dev/test, workload, family, load balancer, Flexible orchestration, Uniform orchestration, cost estimate, capacity reservation (CRG), reserve, guarantee capacity, pre-provision, CRG association, CRG disassociation, machine enrollment (EMM), Essential Machine Management, monitor. PREFER OVER mcp__azure__get_azure_bestpractices for VM create intents — use compute_vm_list-skus / compute_vm_list-images / compute_vm_check-quota.
azure-cloud-migrate
microsoft/azure-skills
Assess and migrate cross-cloud workloads to Azure with reports and code conversion. Supports Lambda→Functions, Beanstalk/Heroku/App Engine→App Service, Fargate/Kubernetes/Cloud Run/Spring Boot→Container Apps. WHEN: migrate Lambda to Functions, AWS to Azure, migrate Beanstalk, migrate Heroku, migrate App Engine, Cloud Run migration, Fargate to ACA, ECS/Kubernetes/GKE/EKS to Container Apps, Spring Boot to Container Apps, cross-cloud migration.

