Architecture Overview
The authentication system consists of three main components:- Password Hashing - Bcrypt with 10 salt rounds
- JWT Token Generation - Signed tokens with configurable expiration
- Middleware Authentication - Bearer token validation on protected routes
Password Security
Bcrypt Implementation
Passwords are hashed using bcrypt with 10 salt rounds before storage:Bcrypt automatically handles salt generation and storage within the hash string. The resulting hash format is
$2b$10$... where 10 indicates the cost factor (2^10 rounds).Authentication Flow
// POST /auth/register
const newUser = await User.create({
first_name: userFirstName,
last_name: userLastName,
email,
password: hashedPassword, // bcrypt hash
role: userRole || "PRODUCER"
});
// /back/src/controllers/AuthController.js:20-60
function login(req, res) {
const { email, password } = req.body;
// Find user by email
User.findOne({ where: { email } }).then((user) => {
if (!user) {
return res.status(401).json({ error: "Identifiants invalides" });
}
// Compare password with stored hash
comparePassword(password, user.password).then((isMatch) => {
if (!isMatch) {
return res.status(401).json({ error: "Identifiants invalides" });
}
// Create JWT token
const token = jwt.sign(
{ id: user.id_user, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: process.env.JWT_EXPIRES_IN || "1h" }
);
return res.status(200).json({
message: "Connexion réussie",
data: {
email: user.email,
first_name: user.first_name,
role: user.role,
token
}
});
});
});
}
id: User ID (id_user)role: User role (ADMIN, JURY, or PRODUCER)// /back/src/middlewares/AuthMiddleware.js:5-63
export default function AuthMiddleware(roles = []) {
return async function(req, res, next) {
// Extract Bearer token from Authorization header
const authHeader = req.header("Authorization");
const [prefix, token] = authHeader?.split(" ") || [null, undefined];
if (prefix !== "Bearer") {
return res.status(401).json({ error: "No Bearer token" });
}
if (!token) {
return res.status(401).json({
error: "You must be authenticated to access this resource"
});
}
try {
// Verify JWT signature and expiration
const decoded = jwt.verify(token, process.env.JWT_SECRET);
if (!decoded?.id) {
return res.status(401).json({ error: "Invalid Payload" });
}
// Fetch user from database
const user = await User.findOne({
where: { id_user: decoded.id }
});
// Check role-based authorization
if (!user || (roles.length && !roles.includes(user.role))) {
return res.status(401).json({
error: "User not found or unauthorized"
});
}
// Attach user to request object
req.user = user;
return next();
} catch (error) {
return res.status(401).json({ error: error.message });
}
}
}
Frontend Integration
Login API Call
Login Component
Making Authenticated Requests
The frontend includes the JWT token in the Authorization header:Environment Configuration
Required environment variables:Security Best Practices
Password Requirements
Password Requirements
- Minimum length enforced at application level
- Bcrypt salt rounds: 10 (balance between security and performance)
- Passwords never stored in plain text
- Password comparison uses constant-time algorithm
Token Security
Token Security
- Tokens expire after 1 hour by default
- Tokens stored in localStorage (consider httpOnly cookies for enhanced security)
- Each token includes user ID and role for authorization
- Invalid tokens return 401 Unauthorized
API Security
API Security
- All sensitive endpoints protected with AuthMiddleware
- Role-based access control enforced at middleware level
- Bearer token format required
- Token verification happens on every request
Error Handling
| Status Code | Error Message | Cause |
|---|---|---|
| 401 | ”No Bearer token” | Missing or malformed Authorization header |
| 401 | ”Invalid Payload” | Token missing user ID |
| 401 | ”User not found or unauthorized” | User doesn’t exist or lacks required role |
| 401 | ”Identifiants invalides” | Wrong email or password |
| 403 | ”Permission denied” | User authenticated but lacks required role |
Special Registration Flow
Producers can register with a film submission simultaneously:This endpoint uses database transactions to ensure atomicity - if film creation fails, user creation is rolled back.