auth0-php

Par auth0 · agent-skills

À utiliser pour ajouter la connexion, la déconnexion et le profil utilisateur à une application web PHP avec authentification par session — intègre le SDK auth0/auth0-php pour les applications à rendu serveur avec les flux login/callback/profile/logout.

npx skills add https://github.com/auth0/agent-skills --skill auth0-php

Intégration Auth0 PHP Web App

Ajoutez connexion, déconnexion et profil utilisateur à une application web PHP en utilisant auth0/auth0-php.


Prérequis

  • PHP 8.2+ avec extensions : mbstring, openssl, json
  • Composer installé
  • Application Web Auth0 Regular Web Application configurée (pas une API - doit être une Application)
  • Si Auth0 n'est pas encore configuré, utilisez d'abord la skill auth0-quickstart

Quand NE PAS l'utiliser

  • PHP APIs avec validation JWT Bearer - Utilisez auth0-php-api pour la validation de tokens d'API sans état
  • Applications Laravel - Utilisez une intégration Laravel dédiée avec auth0/laravel-auth0
  • Applications Symfony - Utilisez une intégration Symfony dédiée avec auth0/symfony
  • Applications monopage - Utilisez auth0-react, auth0-vue ou auth0-angular pour l'auth côté client
  • Applications Next.js - Utilisez auth0-nextjs qui gère client et serveur
  • Applications web Node.js - Utilisez auth0-express ou auth0-fastify pour l'auth basée sur les sessions

Workflow Démarrage Rapide

1. Installer le SDK

composer require auth0/auth0-php vlucas/phpdotenv guzzlehttp/guzzle guzzlehttp/psr7
  • auth0/auth0-php - Le SDK Auth0
  • vlucas/phpdotenv - Charge les fichiers .env dans $_ENV
  • guzzlehttp/guzzle + guzzlehttp/psr7 - Client HTTP PSR-18 requis par le SDK

2. Configurer l'environnement

Créez .env :

AUTH0_DOMAIN=your-tenant.us.auth0.com
AUTH0_CLIENT_ID=your_client_id
AUTH0_CLIENT_SECRET=your_client_secret
AUTH0_COOKIE_SECRET=your_generated_secret
AUTH0_REDIRECT_URI=http://localhost:3000/callback

AUTH0_DOMAIN est votre domaine de tenant Auth0 (sans https://). AUTH0_CLIENT_ID et AUTH0_CLIENT_SECRET proviennent des paramètres de votre Application Auth0. AUTH0_COOKIE_SECRET est utilisé pour chiffrer les cookies de session - générez avec openssl rand -hex 32.

3. Configurer le Dashboard Auth0

Dans les paramètres de votre Application Auth0 :

  • Application Type : Regular Web Application
  • Allowed Callback URLs : http://localhost:3000/callback
  • Allowed Logout URLs : http://localhost:3000

4. Créer la configuration Auth

Créez auth0.php pour initialiser le SDK :

<?php

require 'vendor/autoload.php';

use Auth0\SDK\Auth0;
use Auth0\SDK\Configuration\SdkConfiguration;

// Load environment variables
$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();

$configuration = new SdkConfiguration(
    strategy: SdkConfiguration::STRATEGY_REGULAR,
    domain: $_ENV['AUTH0_DOMAIN'],
    clientId: $_ENV['AUTH0_CLIENT_ID'],
    clientSecret: $_ENV['AUTH0_CLIENT_SECRET'],
    cookieSecret: $_ENV['AUTH0_COOKIE_SECRET'],
    redirectUri: $_ENV['AUTH0_REDIRECT_URI'],
    scope: ['openid', 'profile', 'email'],
);

$auth0 = new Auth0($configuration);

Créez une seule instance Auth0 et réutilisez-la. Ne codez jamais les identifiants en dur - utilisez toujours les variables d'environnement.

Fonctionnement : Le SDK chiffre les données de session (tokens, profil utilisateur) en utilisant AES-256-GCM avec une clé dérivée de cookieSecret via HKDF-SHA256. Les données de session sont stockées dans un cookie chiffré par défaut - aucune base de données côté serveur requise.

5. Créer la page d'accueil (Router)

Créez index.php comme simple contrôleur frontal. Créez d'abord le répertoire routes/ :

<?php

$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

if ($path === '/style.css') {
    header('Content-Type: text/css');
    readfile(__DIR__ . '/style.css');
    exit;
}

require 'auth0.php';

switch ($path) {
    case '/':
        require 'routes/home.php';
        break;
    case '/login':
        require 'routes/login.php';
        break;
    case '/callback':
        require 'routes/callback.php';
        break;
    case '/profile':
        require 'routes/profile.php';
        break;
    case '/logout':
        require 'routes/logout.php';
        break;
    default:
        http_response_code(404);
        echo 'Not found';
        break;
}

Le gestionnaire de fichiers statiques pour /style.css est placé avant require 'auth0.php' afin que les feuilles de style se chargent sans initialiser le SDK.

6. Ajouter la feuille de style

Créez style.css :

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    background: #f5f7fa;
    color: #1a1a2e;
    line-height: 1.6;
    min-height: 100vh;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 40px 20px;
}

.card {
    background: #fff;
    border-radius: 12px;
    padding: 28px;
    margin-bottom: 20px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
    border: 1px solid #e8ecf0;
}

.card.center {
    text-align: center;
    padding: 60px 28px;
}

h1 {
    font-size: 1.5rem;
    font-weight: 600;
    margin-bottom: 4px;
}

h2 {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 16px;
    color: #444;
}

.subtitle {
    color: #666;
    font-size: 0.95rem;
}

.card.center .subtitle {
    margin: 12px 0 28px;
}

.user-header {
    display: flex;
    align-items: center;
    gap: 16px;
}

.avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
}

.avatar-lg {
    width: 72px;
    height: 72px;
}

.nav-links {
    margin-top: 20px;
    display: flex;
    gap: 12px;
}

.top-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}

.btn {
    display: inline-block;
    padding: 10px 20px;
    border-radius: 8px;
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 500;
    transition: all 0.15s ease;
}

.btn-primary {
    background: #635bff;
    color: #fff;
}

.btn-primary:hover {
    background: #4b44d4;
}

.btn-secondary {
    background: #f0f0f5;
    color: #444;
}

.btn-secondary:hover {
    background: #e4e4ec;
}

.btn-back {
    background: none;
    color: #635bff;
    padding: 10px 0;
}

.btn-back:hover {
    color: #4b44d4;
}

.info-table {
    width: 100%;
    border-collapse: collapse;
}

.info-table tr {
    border-bottom: 1px solid #f0f0f5;
}

.info-table tr:last-child {
    border-bottom: none;
}

.info-table td {
    padding: 10px 0;
    vertical-align: top;
}

.info-table .label {
    font-weight: 500;
    color: #666;
    width: 160px;
    font-size: 0.85rem;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.info-table .value {
    color: #1a1a2e;
    word-break: break-all;
}

.token-box {
    background: #f8f9fb;
    border: 1px solid #e8ecf0;
    border-radius: 8px;
    padding: 14px;
    font-size: 0.8rem;
    font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
    word-break: break-all;
    white-space: pre-wrap;
    max-height: 120px;
    overflow-y: auto;
    margin-bottom: 16px;
}

7. Ajouter la route d'accueil

Créez routes/home.php :

<?php

$credentials = $auth0->getCredentials();
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Auth0 PHP App</title>
    <link rel="stylesheet" href="/style.css">
</head>
<body>
    <div class="container">
        <?php if ($credentials): ?>
            <div class="card">
                <div class="user-header">
                    <img src="<?= htmlspecialchars($credentials->user['picture'] ?? '') ?>" alt="avatar" class="avatar" />
                    <div>
                        <h1>Hello, <?= htmlspecialchars($credentials->user['name'] ?? 'User') ?>!</h1>
                        <p class="subtitle"><?= htmlspecialchars($credentials->user['email'] ?? '') ?></p>
                    </div>
                </div>
                <nav class="nav-links">
                    <a href="/profile" class="btn btn-primary">View Profile & Tokens</a>
                    <a href="/logout" class="btn btn-secondary">Logout</a>
                </nav>
            </div>
        <?php else: ?>
            <div class="card center">
                <h1>Auth0 PHP Web App</h1>
                <p class="subtitle">Session-based authentication with Auth0 SDK</p>
                <a href="/login" class="btn btn-primary">Login</a>
            </div>
        <?php endif; ?>
    </div>
</body>
</html>

8. Ajouter la route de connexion

Créez routes/login.php :

<?php

header('Location: ' . $auth0->login());
exit;

login() retourne une URL string pointant vers la page Universal Login d'Auth0. Vous devez rediriger l'utilisateur vers celle-ci.

9. Ajouter la route callback

Créez routes/callback.php :

<?php

if (null !== $auth0->getExchangeParameters()) {
    try {
        $auth0->exchange();
        header('Location: /');
        exit;
    } catch (\Exception $e) {
        error_log('Auth0 callback error: ' . $e->getMessage());
        http_response_code(400);
        echo "Authentication failed. Please try again.";
        exit;
    }
}

header('Location: /');
exit;

getExchangeParameters() vérifie si le callback contient des paramètres de code d'autorisation. exchange() échange le code contre des tokens et établit la session. Enveloppez toujours dans try/catch car l'échange de token peut échouer (par ex. code expiré, non-correspondance CSRF).

10. Ajouter la route de profil (Protégée)

Créez routes/profile.php :

<?php

$credentials = $auth0->getCredentials();

if (null === $credentials) {
    header('Location: /login');
    exit;
}

$user = $credentials->user;
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Profile - Auth0 PHP App</title>
    <link rel="stylesheet" href="/style.css">
</head>
<body>
    <div class="container">
        <nav class="top-nav">
            <a href="/" class="btn btn-back">&larr; Back to Home</a>
            <a href="/logout" class="btn btn-secondary">Logout</a>
        </nav>

        <div class="card">
            <div class="user-header">
                <img src="<?= htmlspecialchars($user['picture'] ?? '') ?>" alt="avatar" class="avatar avatar-lg" />
                <div>
                    <h1><?= htmlspecialchars($user['name'] ?? 'User') ?></h1>
                    <p class="subtitle"><?= htmlspecialchars($user['email'] ?? '') ?></p>
                </div>
            </div>
        </div>

        <div class="card">
            <h2>User Profile Claims</h2>
            <table class="info-table">
                <?php foreach ($user as $key => $value): ?>
                <tr>
                    <td class="label"><?= htmlspecialchars($key) ?></td>
                    <td class="value"><?= htmlspecialchars(is_array($value) ? json_encode($value) : (string)$value) ?></td>
                </tr>
                <?php endforeach; ?>
            </table>
        </div>

        <div class="card">
            <h2>ID Token</h2>
            <pre class="token-box"><?= htmlspecialchars($credentials->idToken ?? 'N/A') ?></pre>
        </div>

        <div class="card">
            <h2>Access Token</h2>
            <pre class="token-box"><?= htmlspecialchars($credentials->accessToken ?? 'N/A') ?></pre>
            <table class="info-table">
                <tr>
                    <td class="label">Expires</td>
                    <td class="value"><?= $credentials->accessTokenExpiration ? date('Y-m-d H:i:s', $credentials->accessTokenExpiration) . ' (' . ($credentials->accessTokenExpired ? 'EXPIRED' : 'valid') . ')' : 'N/A' ?></td>
                </tr>
                <tr>
                    <td class="label">Scopes</td>
                    <td class="value"><?= htmlspecialchars(implode(', ', $credentials->accessTokenScope ?? [])) ?></td>
                </tr>
            </table>
        </div>

        <?php if ($credentials->refreshToken): ?>
        <div class="card">
            <h2>Refresh Token</h2>
            <pre class="token-box"><?= htmlspecialchars($credentials->refreshToken) ?></pre>
        </div>
        <?php endif; ?>
    </div>
</body>
</html>

getCredentials() retourne les données de session de l'utilisateur, ou null s'il n'est pas connecté. La page de profil affiche toutes les revendications d'utilisateur et les tokens pour vérification lors du développement.

11. Ajouter la route de déconnexion

Créez routes/logout.php :

<?php

header('Location: ' . $auth0->logout(returnUri: 'http://localhost:3000'));
exit;

logout() retourne l'URL de déconnexion Auth0. Redirigez l'utilisateur vers celle-ci. Le returnUri est l'endroit où Auth0 envoie l'utilisateur après la déconnexion - il doit être listé dans Allowed Logout URLs. En production, remplacez par votre domaine réel.

12. Tester l'application

php -S localhost:3000 index.php

Visitez http://localhost:3000/login pour démarrer le flux de connexion.


Erreurs Courantes

Erreur Correction
Codage en dur de domain, clientId ou clientSecret dans le code source Lisez toujours depuis les variables d'environnement - ne plongez jamais les identifiants dans le code
Utilisation d'une ancienne version auth0-PHP < 8.0 Requérez PHP 8.2+ et la v8.x du SDK ; les anciennes versions ont des APIs différentes
Installation sans client HTTP PSR-18 Doit avoir un client PSR-18 (par ex. guzzlehttp/guzzle) ou le SDK ne peut pas faire de requêtes HTTP
Utilisation de STRATEGY_API pour une application web Les applications web doivent utiliser SdkConfiguration::STRATEGY_REGULAR pour l'auth basée sur les sessions
Passage de domain comme URL complète avec https:// domain doit être le domaine nu, par ex. my-tenant.us.auth0.com, pas https://my-tenant.us.auth0.com
Oubli de cookieSecret Requis pour le chiffrement de session - sans lui, le SDK lève une ConfigurationException
Non-vérification de getExchangeParameters() avant exchange() Appeler exchange() sans paramètres cause des erreurs ; vérifiez toujours d'abord
Non-gestion des erreurs dans le callback exchange() peut échouer - enveloppez toujours dans try/catch
Application créée comme type SPA dans Auth0 Doit être du type Regular Web Application pour l'auth côté serveur
Non-configuration de l'URL callback dans le Dashboard Auth0 Doit ajouter http://localhost:3000/callback à Allowed Callback URLs
Utilisation directe de $_SESSION Le SDK gère sa propre session de cookie chiffré - n'utilisez pas $_SESSION sauf si vous configurez un SessionStore personnalisé
Déploiement sans cookieSecure: true Doit être mis à true en production - les cookies sont envoyés sur HTTP sinon
Appel de login() ou logout() sans redirection Les deux retournent des strings URL, pas des réponses - doit utiliser header('Location: ...')
"Network error resulted in unfulfilled request" au callback Signifie généralement que AUTH0_CLIENT_SECRET est incorrect, pas un réel problème réseau - vérifiez vos identifiants dans .env

Méthodes SDK clés

Méthode Signature Objectif
login $auth0->login(?string $redirectUrl, ?array $params): string Retourne une string d'URL d'autorisation - redirigez l'utilisateur vers celle-ci
exchange $auth0->exchange(?string $redirectUri, ?string $code, ?string $state): bool Échange le code d'autorisation contre des tokens, établit la session
getCredentials $auth0->getCredentials(): ?object Retourne les identifiants de session actuels ou null
getExchangeParameters $auth0->getExchangeParameters(): ?object Vérifie si le callback contient les paramètres d'échange
logout $auth0->logout(?string $returnUri, ?array $params): string Retourne la string d'URL de déconnexion Auth0
renew $auth0->renew(?array $params): self Rafraîchit le token d'accès expiré (requiert le scope offline_access)
clear $auth0->clear(bool $transient = true): self Efface la session locale sans déconnexion Auth0

Objet Credentials

Après une authentification réussie, getCredentials() retourne un objet avec :

$credentials = $auth0->getCredentials();

$credentials->user;                    // array - revendications du profil utilisateur
$credentials->idToken;                 // string - token ID brut
$credentials->accessToken;             // string - token d'accès
$credentials->refreshToken;            // string|null - token d'actualisation (requiert offline_access)
$credentials->accessTokenExpiration;   // int - timestamp d'expiration
$credentials->accessTokenExpired;      // bool - si le token est expiré
$credentials->accessTokenScope;        // array - scopes accordés

Revendications du profil utilisateur ($credentials->user) :

  • sub - identifiant utilisateur unique
  • name, nickname, picture
  • email, email_verified
  • given_name, family_name
  • updated_at, locale

Skills Connexes

  • auth0-php-api - Pour protéger les APIs PHP avec validation de token Bearer JWT
  • auth0-quickstart - Configuration Auth0 basique et détection de framework
  • auth0-cli - Gérer les ressources Auth0 depuis le terminal
  • auth0-mfa - Ajouter l'authentification multi-facteurs

Référence Rapide

SdkConfiguration pour les applications web :

$configuration = new SdkConfiguration(
    strategy: SdkConfiguration::STRATEGY_REGULAR,        // required
    domain: $_ENV['AUTH0_DOMAIN'],                        // required
    clientId: $_ENV['AUTH0_CLIENT_ID'],                   // required
    clientSecret: $_ENV['AUTH0_CLIENT_SECRET'],           // required
    cookieSecret: $_ENV['AUTH0_COOKIE_SECRET'],           // required
    redirectUri: $_ENV['AUTH0_REDIRECT_URI'],             // required
    scope: ['openid', 'profile', 'email'],               // recommended
);

Modèle de protection de route :

$credentials = $auth0->getCredentials();
if (null === $credentials) {
    header('Location: /login');
    exit;
}

Variables d'environnement :

  • AUTH0_DOMAIN - votre domaine de tenant Auth0 (par ex. tenant.us.auth0.com)
  • AUTH0_CLIENT_ID - ID client de votre Application
  • AUTH0_CLIENT_SECRET - secret client de votre Application
  • AUTH0_COOKIE_SECRET - clé secrète de chiffrement (générez : openssl rand -hex 32)
  • AUTH0_REDIRECT_URI - URL de callback (par ex. http://localhost:3000/callback)

Documentation Détaillée

  • Setup Guide - Scripts de configuration automatisée, configuration d'environnement, utilisation de l'Auth0 CLI
  • Integration Guide - Routes protégées, appel d'APIs, gestion de session, gestion des erreurs
  • API Reference - API SDK Auth0 complète, options de configuration, stockage de session, sécurité

Références

Skills similaires