Guides pratiques

Code QR

Des codes QR animés sont utilisés avec ExcelID quand l’utilisateur visite votre service sur un appareil, par exemple un ordinateur, mais utilise ExcelID sur un autre, son téléphone. Le parcours est le suivant :

  1. Votre service génère un code QR.
  2. Votre service le présente à l’utilisateur.
  3. L’utilisateur le scanne avec son application ExcelID.

Si le code est valide, l’application poursuit la demande.

Animation et délais

Pour renforcer la sécurité, on utilise des codes QR animés : votre service met à jour le code en continu, ce qui rend la fraude à distance plus difficile.

Accessibilité

Génération du code QR

Les codes QR sont générés chez vous. De nombreuses bibliothèques tierces existent. Pour la génération, utilisez le schéma excelid.qrStartToken.time.qrAuthCode comme contenu du code QR, où :

qrStartSecret ne doit pas être envoyé à votre frontend. C’est un secret partagé uniquement entre le service ExcelID et votre backend.

Conseils et recommandations

Si le code QR est trop ancien, l’application le refuse : vous devez créer une nouvelle demande et l’utilisateur doit recommencer. ExcelID accepte un code dont le temps est au plus 2 secondes en avance et 10 secondes en retard sur le temps réel de la demande.

Exemple

Si le qrStartToken est a41d8e0b-52c7-4d39-9e66-0b7c2f1a8d54 et le qrStartSecret est 0c9b7a1e-6d58-4f0b-a2b3-9d41e6c8f7a5, alors :

TempsContenu du code QR
0 sexcelid.a41d8e0b-52c7-4d39-9e66-0b7c2f1a8d54.0.2eaf777f169f8a7add2fc1c1180275de11226dfdc6ea59fe8fc4a15942b09747
1 sexcelid.a41d8e0b-52c7-4d39-9e66-0b7c2f1a8d54.1.c95bffa08846f84d2ebfe173c3e23fc04d956caff73252f6e189ad7c7a2c2fc7
2 sexcelid.a41d8e0b-52c7-4d39-9e66-0b7c2f1a8d54.2.303d9075e4ec91fb02731202942e819b0d18e6cefd92ce81400682bb2fcbde9e

Calculer le code sur votre serveur

import { createHmac } from 'node:crypto';

// order = réponse de /auth ; startedAt = Date.now() au moment de la réponse
function qrData(order, startedAt) {
  const time = Math.floor((Date.now() - startedAt) / 1000);
  const code = createHmac('sha256', order.qrStartSecret).update(String(time)).digest('hex');
  return `excelid.${order.qrStartToken}.${time}.${code}`;
}

// Route appelée chaque seconde par la page : elle ne renvoie que le texte du code
app.get('/login/:id/qr', (req, res) => {
  const session = sessions.get(req.params.id);
  if (!session) return res.sendStatus(404);
  res.json({ qr: qrData(session.order, session.startedAt) });
});