Aller au contenu principal

Quickstart JavaScript Vanilla

Ajoutez l'authentification à n'importe quelle application JavaScript sans frameworks.


Avant de commencer

info

Vous avez besoin de ces identifiants avant de commencer. Obtenez-les depuis le Tableau de bord SyAuth.

Ce dont vous avez besoinOù le trouverExemple
Client IDTableau de bord → Clients OAuth → Votre Appa1b2c3d4-5678-90ab-cdef-...

Nouveau sur SyAuth ? Suivez d'abord ces étapes :

  1. Créez un compte Nexorix (SyAuth utilise Nexorix pour l'authentification)
  2. Créez votre premier Client OAuth pour obtenir votre Client ID
  3. Choisissez le type Client Public (pour les apps navigateur sans backend)
  4. Ajoutez votre URL de callback (ex : http://localhost:3000/callback.html) comme URI de redirection

Prérequis

  • Une application HTML/JS de base (aucun framework requis)
  • Un navigateur moderne avec le support de l'API Web Crypto (tous les navigateurs modernes)

Comment ça fonctionne

Voici ce qui se passe quand un utilisateur se connecte :


Étape 1 : Créer la Configuration

Créez un fichier JavaScript avec votre configuration SyAuth :

// syauth-config.js

const SyAuthConfig = {
// L'endpoint API SyAuth (ne changez pas ceci sauf si auto-hébergé)
apiUrl: 'https://api.syauth.com/e/v1',

// Votre Client ID depuis Tableau de bord → Clients OAuth → Votre App
clientId: 'votre-client-id-ici',

// Où SyAuth redirige après la connexion - doit correspondre à la config du Tableau de bord !
redirectUri: 'http://localhost:3000/callback.html',

// Permissions à demander (openid profile email est standard)
scope: 'openid profile email',
};
astuce

Où trouver votre Client ID :

  1. Connectez-vous à syauth.com/dashboard
  2. Sélectionnez votre Espace de travail
  3. Cliquez sur Clients OAuth dans la barre latérale
  4. Cliquez sur votre application
  5. Copiez le Client ID

Étape 2 : Créer les Fonctions Utilitaires PKCE

PKCE est une fonctionnalité de sécurité qui protège contre les attaques par interception de code d'autorisation. C'est requis pour les applications basées sur navigateur.

// syauth-crypto.js

/**
* Génère une chaîne cryptographiquement aléatoire pour PKCE
* @returns {string} Une chaîne aléatoire URL-safe
*/
function generateRandomString(length = 64) {
const array = new Uint8Array(length);
crypto.getRandomValues(array);

// Convertir en base64 URL-safe
return btoa(String.fromCharCode(...array))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}

/**
* Crée un hash SHA-256 du code verifier pour PKCE
* @param {string} codeVerifier - La chaîne aléatoire à hacher
* @returns {Promise<string>} Hash encodé en Base64URL
*/
async function generateCodeChallenge(codeVerifier) {
// Encoder le verifier en octets
const encoder = new TextEncoder();
const data = encoder.encode(codeVerifier);

// Créer le hash SHA-256
const digest = await crypto.subtle.digest('SHA-256', data);

// Convertir en base64 URL-safe
return btoa(String.fromCharCode(...new Uint8Array(digest)))
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=+$/, '');
}

Étape 3 : Créer le Module d'Auth

Ce module gère la connexion, la déconnexion et la gestion des tokens :

// syauth-auth.js

const SyAuth = {
/**
* Initie le flux de connexion en redirigeant vers SyAuth
*/
async login() {
// Étape 1 : Générer les codes PKCE
const codeVerifier = generateRandomString(64);
const codeChallenge = await generateCodeChallenge(codeVerifier);

// Étape 2 : Générer l'état pour la protection CSRF
const state = generateRandomString(32);

// Étape 3 : Stocker ceux-ci pour plus tard (nous en aurons besoin dans le callback)
sessionStorage.setItem('syauth_code_verifier', codeVerifier);
sessionStorage.setItem('syauth_state', state);

// Étape 4 : Construire l'URL d'autorisation
const params = new URLSearchParams({
response_type: 'code',
client_id: SyAuthConfig.clientId,
redirect_uri: SyAuthConfig.redirectUri,
scope: SyAuthConfig.scope,
state: state,
code_challenge: codeChallenge,
code_challenge_method: 'S256',
});

// Étape 5 : Rediriger l'utilisateur vers la page de connexion SyAuth
window.location.href = `${SyAuthConfig.apiUrl}/oauth/authorize?${params}`;
},

/**
* Gère le callback OAuth après la connexion
* Appelez ceci sur votre page de callback
* @returns {Promise<Object>} Les tokens de l'utilisateur authentifié
*/
async handleCallback() {
const params = new URLSearchParams(window.location.search);
const code = params.get('code');
const state = params.get('state');
const error = params.get('error');

// Vérifier les erreurs de SyAuth
if (error) {
throw new Error(`Authentification échouée : ${error}`);
}

// Vérifier que nous avons un code d'autorisation
if (!code) {
throw new Error('Aucun code d\'autorisation reçu');
}

// SÉCURITÉ : Vérifier que l'état correspond à ce que nous avons envoyé (empêche CSRF)
const storedState = sessionStorage.getItem('syauth_state');
if (state !== storedState) {
throw new Error('État invalide - attaque CSRF possible !');
}

// Obtenir le verifier PKCE que nous avons stocké plus tôt
const codeVerifier = sessionStorage.getItem('syauth_code_verifier');
if (!codeVerifier) {
throw new Error('Verifier PKCE manquant - avez-vous commencé par /login ?');
}

// Échanger le code d'autorisation contre des tokens
const response = await fetch(`${SyAuthConfig.apiUrl}/oauth/token`, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
grant_type: 'authorization_code',
client_id: SyAuthConfig.clientId,
code: code,
redirect_uri: SyAuthConfig.redirectUri,
code_verifier: codeVerifier,
}),
});

if (!response.ok) {
const error = await response.json();
throw new Error(error.error_description || 'Échange de token échoué');
}

const tokens = await response.json();

// Stocker les tokens (utilisation de sessionStorage pour la démo - voir note de sécurité ci-dessous)
sessionStorage.setItem('syauth_access_token', tokens.access_token);
if (tokens.refresh_token) {
sessionStorage.setItem('syauth_refresh_token', tokens.refresh_token);
}

// Nettoyer les données PKCE
sessionStorage.removeItem('syauth_code_verifier');
sessionStorage.removeItem('syauth_state');

return tokens;
},

/**
* Obtient le token d'accès actuel
* @returns {string|null}
*/
getAccessToken() {
return sessionStorage.getItem('syauth_access_token');
},

/**
* Vérifie si l'utilisateur est authentifié
* @returns {boolean}
*/
isAuthenticated() {
return !!this.getAccessToken();
},

/**
* Récupère le profil de l'utilisateur actuel
* @returns {Promise<Object>} Données de profil utilisateur
*/
async getUser() {
const token = this.getAccessToken();
if (!token) {
throw new Error('Non authentifié');
}

const response = await fetch(`${SyAuthConfig.apiUrl}/api/user/profile/`, {
headers: { 'Authorization': `Bearer ${token}` },
});

if (!response.ok) {
throw new Error('Échec de la récupération du profil utilisateur');
}

return response.json();
},

/**
* Déconnecte l'utilisateur
*/
logout() {
sessionStorage.removeItem('syauth_access_token');
sessionStorage.removeItem('syauth_refresh_token');

// Optionnellement rediriger vers la page de connexion
window.location.href = '/';
},
};
ATTENTION

Note de Sécurité : En production, évitez de stocker les tokens dans localStorage ou sessionStorage car ils sont vulnérables aux attaques XSS. Envisagez :

  • Utiliser des cookies HTTP-only (nécessite un backend)
  • Stocker les tokens en mémoire uniquement
  • Utiliser un proxy backend sécurisé pour les appels API

Étape 4 : Créer Vos Pages HTML

Page de Connexion (index.html)

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mon App</title>
</head>
<body>
<div id="app">
<h1>Bienvenue sur Mon App</h1>

<!-- Afficher ceci quand NON connecté -->
<div id="login-section">
<p>Veuillez vous connecter pour continuer.</p>
<button onclick="SyAuth.login()">Se connecter avec SyAuth</button>
</div>

<!-- Afficher ceci quand connecté -->
<div id="user-section" style="display: none;">
<p>Bienvenue, <span id="user-name"></span> !</p>
<p>Email : <span id="user-email"></span></p>
<button onclick="SyAuth.logout()">Se déconnecter</button>
</div>
</div>

<!-- Inclure les scripts dans l'ordre -->
<script src="syauth-config.js"></script>
<script src="syauth-crypto.js"></script>
<script src="syauth-auth.js"></script>
<script>
// Vérifier si l'utilisateur est authentifié au chargement de la page
async function init() {
if (SyAuth.isAuthenticated()) {
try {
const user = await SyAuth.getUser();

// Afficher les infos utilisateur
document.getElementById('user-name').textContent = user.first_name;
document.getElementById('user-email').textContent = user.email;

document.getElementById('login-section').style.display = 'none';
document.getElementById('user-section').style.display = 'block';
} catch (error) {
// Le token peut être expiré
console.error('Échec de la vérification auth :', error);
SyAuth.logout();
}
}
}

init();
</script>
</body>
</html>

Page de Callback (callback.html)

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Authentification...</title>
</head>
<body>
<div id="message">
<p>Authentification en cours, veuillez patienter...</p>
</div>

<script src="syauth-config.js"></script>
<script src="syauth-crypto.js"></script>
<script src="syauth-auth.js"></script>
<script>
async function processCallback() {
try {
await SyAuth.handleCallback();

// Succès ! Rediriger vers l'app principale
window.location.href = '/';

} catch (error) {
// Afficher l'erreur à l'utilisateur
document.getElementById('message').innerHTML = `
<h2>Authentification Échouée</h2>
<p style="color: red;">${error.message}</p>
<a href="/">Retourner et réessayer</a>
`;
}
}

processCallback();
</script>
</body>
</html>

Structure des Fichiers

Votre projet devrait ressembler à ceci :

votre-projet/
├── index.html # Page principale avec bouton de connexion
├── callback.html # Gestionnaire de callback OAuth
├── syauth-config.js # Votre configuration SyAuth
├── syauth-crypto.js # Fonctions utilitaires PKCE
└── syauth-auth.js # Module d'authentification

Testez Votre Intégration

  1. Démarrez un serveur local (exemple Python) :

    python -m http.server 3000
  2. Ouvrez http://localhost:3000

  3. Cliquez sur "Se connecter avec SyAuth"

    • Vous serez redirigé vers la page de connexion SyAuth
    • Connectez-vous ou créez un compte
    • Vous serez redirigé vers votre application, maintenant authentifié !

Terminé ! 🎉

Votre application JavaScript vanilla a maintenant :

  • ✅ OAuth 2.0 avec PKCE (sécurisé même dans les navigateurs)
  • ✅ Aucune dépendance de framework
  • ✅ Fonctionnalité de connexion et déconnexion
  • ✅ Récupération du profil utilisateur

Dépannage

Erreur "Invalid redirect_uri"

Cause : L'URI de redirection ne correspond pas à la configuration de votre Tableau de bord.

Solution :

  1. Allez dans Tableau de bord → Clients OAuth → Votre App → URIs de redirection
  2. Assurez-vous que http://localhost:3000/callback.html est listé exactement

Erreur "Invalid state"

Cause : Non-correspondance de l'état - arrive généralement si vous ouvrez la connexion dans un nouvel onglet.

Solution : Commencez toujours la connexion depuis le même onglet. Ne partagez pas les URLs de connexion.

Erreur "Missing PKCE verifier"

Cause : La page de callback a été chargée sans passer par la connexion d'abord.

Solution : Ne naviguez pas directement vers /callback.html. Commencez toujours par le flux de connexion.

Erreurs CORS

Cause : Essayer d'appeler l'API depuis une URL file:// ou une mauvaise origine.

Solution : Utilisez un serveur HTTP local (comme python -m http.server) au lieu d'ouvrir les fichiers HTML directement.


Prochaines Étapes