Le système d'authentification de Veko.js est intégré directement dans le core du framework et offre une solution complète et flexible pour gérer l'authentification des utilisateurs.
- Installation et Configuration
- Types de Configuration
- Base de Données
- Routes API
- Routes Web (EJS)
- Middlewares
- Vues Automatiques
- Exemples Pratiques
- API Reference
const { createApp } = require('veko.js');
const app = createApp();
// Activer l'authentification avec configuration par défaut
await app.enableAuth();await app.enableAuth({
database: {
type: 'sqlite', // ou 'mysql'
sqlite: {
path: './data/users.db'
},
mysql: {
host: 'localhost',
port: 3306,
database: 'my_app',
username: 'root',
password: 'password'
}
},
session: {
secret: 'votre-secret-super-securise',
maxAge: 7 * 24 * 60 * 60 * 1000, // 7 jours
secure: false // true en production avec HTTPS
},
routes: {
api: {
login: '/api/auth/login',
logout: '/api/auth/logout',
register: '/api/auth/register',
check: '/api/auth/check',
profile: '/api/auth/profile'
},
web: {
enabled: true,
login: '/auth/login',
logout: '/auth/logout',
register: '/auth/register',
dashboard: '/auth/dashboard'
}
},
redirects: {
afterLogin: '/auth/dashboard',
afterLogout: '/auth/login',
loginRequired: '/auth/login'
},
password: {
minLength: 8,
requireSpecial: false,
requireNumbers: true
},
views: {
enabled: true,
autoCreate: true
}
});Pour les applications qui utilisent leurs propres interfaces utilisateur ou des frameworks frontend :
await app.enableAuth({
routes: {
web: { enabled: false }
},
views: { enabled: false }
});Avantages :
- Léger et performant
- Idéal pour les API REST
- Compatible avec React, Vue, Angular, etc.
Pour les applications traditionnelles avec rendu côté serveur :
await app.enableAuth({
routes: {
web: { enabled: true }
},
views: { enabled: true }
});Avantages :
- Interface utilisateur complète fournie
- Vues Bootstrap responsives
- Prêt à l'emploi
Pour les applications hybrides :
await app.enableAuth({
routes: {
web: { enabled: true }
},
views: { enabled: false } // Utiliser ses propres vues
});database: {
type: 'sqlite',
sqlite: {
path: './data/users.db'
}
}Avantages :
- Aucune configuration requise
- Idéal pour le développement
- Fichier unique portable
database: {
type: 'mysql',
mysql: {
host: 'localhost',
port: 3306,
database: 'my_app',
username: 'root',
password: 'password'
}
}Avantages :
- Performance en production
- Gestion avancée des utilisateurs
- Support des transactions
-- SQLite
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE NOT NULL,
email TEXT UNIQUE NOT NULL,
password TEXT NOT NULL,
role TEXT DEFAULT 'user',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
-- MySQL
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(255) UNIQUE NOT NULL,
email VARCHAR(255) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
role VARCHAR(50) DEFAULT 'user',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);Les routes API sont toujours activées et fournissent une interface RESTful complète.
Connecter un utilisateur.
Requête :
{
"username": "john_doe",
"password": "motdepasse123"
}Réponse (succès) :
{
"success": true,
"message": "Connexion réussie",
"user": {
"id": 1,
"username": "john_doe",
"email": "john@example.com",
"role": "user"
}
}Réponse (erreur) :
{
"success": false,
"message": "Nom d'utilisateur ou mot de passe incorrect"
}Créer un nouveau compte utilisateur.
Requête :
{
"username": "jane_doe",
"email": "jane@example.com",
"password": "motdepasse123",
"confirmPassword": "motdepasse123"
}Réponse (succès) :
{
"success": true,
"message": "Inscription réussie",
"user": {
"id": 2,
"username": "jane_doe",
"email": "jane@example.com",
"role": "user"
}
}Déconnecter l'utilisateur actuel.
Réponse :
{
"success": true,
"message": "Déconnexion réussie"
}Vérifier l'état d'authentification.
Réponse (connecté) :
{
"authenticated": true,
"user": {
"id": 1,
"username": "john_doe",
"email": "john@example.com",
"role": "user"
}
}Réponse (non connecté) :
{
"authenticated": false,
"user": null
}Récupérer le profil de l'utilisateur connecté (authentification requise).
Réponse :
{
"success": true,
"user": {
"id": 1,
"username": "john_doe",
"email": "john@example.com",
"role": "user"
}
}Mettre à jour le profil de l'utilisateur connecté (authentification requise).
Requête :
{
"email": "newemail@example.com"
}Réponse :
{
"success": true,
"message": "Profil mis à jour",
"user": {
"id": 1,
"username": "john_doe",
"email": "newemail@example.com",
"role": "user"
}
}Les routes web fournissent une interface utilisateur complète avec des vues EJS.
Affiche la page de connexion.
Traite le formulaire de connexion et redirige vers le dashboard.
Affiche la page d'inscription.
Traite le formulaire d'inscription et redirige vers le dashboard.
Déconnecte l'utilisateur et redirige vers la page de connexion.
Affiche le tableau de bord utilisateur (authentification requise).
// Route protégée (authentification requise)
app.createRoute('get', '/profile', app.requireAuth(), (req, res) => {
res.render('profile', {
user: req.session.user
});
});
// Route avec rôle spécifique
app.createRoute('get', '/admin', app.requireRole('admin'), (req, res) => {
res.render('admin', {
user: req.session.user
});
});
// Middleware pour plusieurs routes
app.use('/admin/*', app.requireRole('admin'));Les variables suivantes sont automatiquement disponibles dans toutes les vues EJS :
// Dans vos templates EJS
<% if (isAuthenticated) { %>
<p>Bonjour <%= user.username %> !</p>
<a href="/auth/logout">Déconnexion</a>
<% } else { %>
<a href="/auth/login">Connexion</a>
<% } %>// Vérifier si l'utilisateur est connecté
if (app.auth.isAuthenticated(req)) {
// L'utilisateur est connecté
}
// Récupérer l'utilisateur actuel
const user = app.auth.getCurrentUser(req);
// Déconnecter l'utilisateur
await app.auth.logout(req);Le système crée automatiquement des vues Bootstrap responsives si views.enabled et views.autoCreate sont à true.
views/
└── auth/
├── login.ejs
├── register.ejs
└── dashboard.ejs
Vous pouvez créer vos propres vues en désactivant les vues automatiques :
await app.enableAuth({
views: { enabled: false }
});Puis créer vos propres fichiers dans views/auth/ :
<!-- views/auth/login.ejs -->
<!DOCTYPE html>
<html>
<head>
<title>Ma Page de Connexion</title>
</head>
<body>
<h1>Connexion</h1>
<% if (error) { %>
<div class="error">
<% if (error === 'invalid_credentials') { %>
Identifiants incorrects
<% } else { %>
Une erreur est survenue
<% } %>
</div>
<% } %>
<form method="POST">
<input type="text" name="username" placeholder="Nom d'utilisateur" required>
<input type="password" name="password" placeholder="Mot de passe" required>
<button type="submit">Se connecter</button>
</form>
</body>
</html>// server.js
const { createApp } = require('veko.js');
async function startServer() {
const app = createApp({ port: 3000 });
// API seulement
await app.enableAuth({
routes: { web: { enabled: false } },
views: { enabled: false },
database: { type: 'sqlite' }
});
// Route publique
app.createRoute('get', '/', (req, res) => {
res.json({ message: 'API prête' });
});
// Route protégée
app.createRoute('get', '/protected', app.requireAuth(), (req, res) => {
res.json({
message: 'Données protégées',
user: req.session.user
});
});
app.loadRoutes();
app.listen(3000);
}
startServer();// Frontend React - Login.js
import React, { useState } from 'react';
function Login() {
const [credentials, setCredentials] = useState({ username: '', password: '' });
const handleSubmit = async (e) => {
e.preventDefault();
const response = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(credentials)
});
const data = await response.json();
if (data.success) {
// Rediriger vers le dashboard
window.location.href = '/dashboard';
} else {
alert(data.message);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="Nom d'utilisateur"
value={credentials.username}
onChange={(e) => setCredentials({...credentials, username: e.target.value})}
/>
<input
type="password"
placeholder="Mot de passe"
value={credentials.password}
onChange={(e) => setCredentials({...credentials, password: e.target.value})}
/>
<button type="submit">Se connecter</button>
</form>
);
}// server.js
const { startDevFullAuth } = require('veko.js');
startDevFullAuth({
port: 3000,
auth: {
database: {
type: 'mysql',
mysql: {
host: 'localhost',
database: 'my_blog',
username: 'root',
password: 'password'
}
},
routes: {
web: {
login: '/connexion',
register: '/inscription',
dashboard: '/tableau-bord'
}
}
}
}).then(() => {
console.log('Blog démarré sur http://localhost:3000');
});// server.js
const { createApp } = require('veko.js');
async function startEcommerce() {
const app = createApp({ port: 3000 });
await app.enableAuth({
database: { type: 'mysql' },
password: {
minLength: 8,
requireNumbers: true,
requireSpecial: true
},
redirects: {
afterLogin: '/account',
afterLogout: '/',
loginRequired: '/login'
}
});
// Page d'accueil publique
app.createRoute('get', '/', (req, res) => {
res.render('home', {
title: 'Boutique en ligne',
user: res.locals.user
});
});
// Espace client (authentification requise)
app.createRoute('get', '/account', app.requireAuth(), (req, res) => {
res.render('account', {
title: 'Mon compte',
user: req.session.user
});
});
// Administration (rôle admin requis)
app.use('/admin/*', app.requireRole('admin'));
app.createRoute('get', '/admin/dashboard', (req, res) => {
res.render('admin/dashboard', {
title: 'Administration',
user: req.session.user
});
});
app.loadRoutes();
app.listen(3000);
}
startEcommerce();// server.js
const { createApp } = require('veko.js');
async function startMixedApp() {
const app = createApp({ port: 3000 });
// Configuration mixte : API + Web avec vues personnalisées
await app.enableAuth({
routes: {
web: { enabled: true }
},
views: { enabled: false }, // Utiliser nos propres vues
database: { type: 'sqlite' }
});
// Les routes API sont disponibles pour l'app mobile
// Les routes web sont disponibles pour l'interface web
// Vues personnalisées dans views/auth/
app.loadRoutes();
app.listen(3000);
}
startMixedApp();Initialise le système d'authentification.
Vérifie si l'utilisateur est connecté.
- Paramètres :
req- Objet request Express - Retour :
boolean
Récupère l'utilisateur actuel.
- Paramètres :
req- Objet request Express - Retour :
Object|null
Middleware d'authentification.
- Retour : Middleware Express
Middleware de vérification de rôle.
- Paramètres :
role- Rôle requis ('admin', 'user', etc.) - Retour : Middleware Express
Déconnecte l'utilisateur.
- Paramètres :
req- Objet request Express - Retour :
Promise<boolean>
Active/désactive les routes web.
- Paramètres :
enabled- Boolean
Active/désactive les vues automatiques.
- Paramètres :
enabled- Boolean
{
database: {
type: 'sqlite',
sqlite: { path: './data/auth.db' },
mysql: {
host: 'localhost',
port: 3306,
database: 'veko_auth',
username: 'root',
password: ''
}
},
session: {
secret: 'veko-auth-secret-change-me',
maxAge: 24 * 60 * 60 * 1000, // 24 heures
secure: false
},
routes: {
api: {
login: '/api/auth/login',
logout: '/api/auth/logout',
register: '/api/auth/register',
check: '/api/auth/check',
profile: '/api/auth/profile'
},
web: {
enabled: true,
login: '/auth/login',
logout: '/auth/logout',
register: '/auth/register',
dashboard: '/auth/dashboard'
}
},
redirects: {
afterLogin: '/auth/dashboard',
afterLogout: '/auth/login',
loginRequired: '/auth/login'
},
password: {
minLength: 6,
requireSpecial: false,
requireNumbers: false
},
views: {
enabled: true,
autoCreate: true
}
}- Secret de session : Utilisez toujours un secret fort et unique
session: {
secret: process.env.SESSION_SECRET || 'votre-secret-complexe'
}- HTTPS en production :
session: {
secure: process.env.NODE_ENV === 'production'
}- Mots de passe sécurisés :
password: {
minLength: 8,
requireSpecial: true,
requireNumbers: true
}- Base de données sécurisée :
database: {
type: 'mysql',
mysql: {
host: process.env.DB_HOST,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD
}
}Les mots de passe sont automatiquement hachés avec bcrypt avant stockage. Le système utilise un salt automatique pour chaque mot de passe.
Pour les formulaires web, ajoutez une protection CSRF :
const csrf = require('csurf');
app.use(csrf());
// Dans vos vues EJS
<form method="POST">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<!-- ... autres champs ... -->
</form>❌ Erreur lors de l'initialisation de l'authentification: ENOENT: no such file or directory
Solution : Vérifiez le chemin de la base de données SQLite ou les paramètres MySQL.
📦 Installation de express-session...
Normal : Le système installe automatiquement les dépendances nécessaires.
Cause : Secret de session changé ou configuration cookie incorrecte. Solution : Utilisez un secret fixe et vérifiez la configuration des cookies.
Activez le mode debug pour plus d'informations :
const app = createApp({ isDev: true });Si vous migrez depuis une version antérieure, les anciennes configurations restent compatibles :
// Ancienne syntaxe (toujours supportée)
await app.enableAuth({
routes: { web: { enabled: false } },
views: { enabled: false }
});
// Nouvelle syntaxe équivalente
await app.enableAuth({
routes: { web: { enabled: false } },
views: { enabled: false }
});Avant toute mise à jour, sauvegardez votre base de données :
# SQLite
cp ./data/auth.db ./data/auth.db.backup
# MySQL
mysqldump -u root -p my_app > backup.sqlVeko.js Auth System - Documentation complète v1.0
Pour plus d'informations, consultez les exemples dans le dossier /examples/ du projet.