Pour sites web et blogs

Un quiz pour ton site

Choisis un set de questions, règle les couleurs et les textes, puis copie le code dans ta page. À chaque visite, 9 autres questions gratuites apparaissent et chaque réponse remplit la mosaïque.

Contenu
Apparence
Textes

Aperçu

Code d'intégration

Colle le code à l'endroit de ta page où le quiz doit apparaître.

Bon à savoir

Facultatif : intégration via ton propre domaine

Si tu ne veux aucune requête vers des serveurs tiers, ton serveur web livre le quiz : il transmet un chemin comme /qwissit/ à Qwissit. Le navigateur de tes visiteurs ne parle alors qu'à ton domaine, et Qwissit ne voit que l'adresse de ton serveur. L'intégration directe ci-dessus reste la solution simple par défaut.

1. Configure ton serveur web : transmets /qwissit/ à https://www.qwissit.com/widget/v1/, sans cookies, adresse IP ni autres données de tes visiteurs.

nginx
location ^~ /qwissit/ {
    proxy_pass https://www.qwissit.com/widget/v1/;
    proxy_set_header Host www.qwissit.com;
    proxy_ssl_server_name on;
    proxy_set_header X-Forwarded-For "";
    proxy_set_header X-Real-IP "";
    proxy_set_header Cookie "";
    proxy_set_header Referer "";
    proxy_set_header User-Agent "qwissit-proxy";
    proxy_hide_header Set-Cookie;
}
Apache (mod_proxy, mod_ssl, mod_headers)
SSLProxyEngine On
<Location "/qwissit/">
    ProxyPass "https://www.qwissit.com/widget/v1/"
    ProxyAddHeaders Off
    RequestHeader unset Cookie
    RequestHeader unset Referer
    RequestHeader set User-Agent "qwissit-proxy"
    Header unset Set-Cookie
</Location>
Caddy
handle_path /qwissit/* {
    rewrite * /widget/v1{path}?{query}
    reverse_proxy https://www.qwissit.com {
        header_up Host {upstream_hostport}
        header_up -X-Forwarded-For
        header_up -Cookie
        header_up -Referer
        header_up User-Agent qwissit-proxy
        header_down -Set-Cookie
    }
}
PHP (Shared Hosting)

Pas d'accès à la configuration du serveur (hébergement mutualisé) ? Télécharge le fichier PHP, enregistre-le sous qwissit-proxy.php dans ton dossier web et utilise /qwissit-proxy.php/qwissit-widget.js comme adresse du script. Il ne transmet que les fichiers du widget.

Télécharger qwissit-proxy.php

2. Remplace l'adresse du script dans le code ci-dessus :

<script src="/qwissit/qwissit-widget.js" async></script>

3. Test : l'appel avec ton domaine doit renvoyer 200 et content-type: text/javascript. Un 404 renvoie à un point de « Si ça ne marche pas », une page HTML signifie que ton CMS a repris la requête.

curl -I https://example.org/qwissit/qwissit-widget.js

Ensuite dans le navigateur avec les outils de développement (F12), onglet « Réseau » : aucune requête vers www.qwissit.com ne doit apparaître.

Si ça ne marche pas
  • nginx renvoie 404 : les règles pour fichiers statiques comme location ~* \.(js|css)$ l'emportent sur les règles de préfixe simples, et nginx cherche qwissit-widget.js sur ton serveur. C'est pourquoi l'extrait indique location ^~ /qwissit/ : le ^~ garantit que ce chemin est toujours transmis.
  • Les changements ne prennent effet qu'après un rechargement : nginx -t && nginx -s reload, pour Apache apachectl configtest && systemctl reload apache2. Sous Docker, avec un fichier de configuration monté seul, le conteneur continue de voir l'ancienne version après remplacement du fichier (rsync, cp) – seul un redémarrage du conteneur aide alors (docker compose restart <service>).
  • Apache : les modules proxy, proxy_http, ssl et headers doivent être actifs (a2enmod proxy proxy_http ssl headers). Les règles vont dans la configuration du serveur ou du VirtualHost, pas dans le .htaccess. Si tu ne peux utiliser que le .htaccess, prends le fichier PHP.
  • Fichier PHP : il doit vraiment se trouver dans le dossier web (pour TYPO3 dans public/), sinon le CMS reprend la requête. Le serveur doit transmettre à PHP le chemin après le fichier (PATH_INFO) : sous Apache AcceptPathInfo On (par défaut chez beaucoup d'hébergeurs), sous nginx dans la règle PHP ainsi :
    location ~ \.php(/|$) {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        # … your usual fastcgi_pass / include fastcgi_params
    }

Facultatif : vérifier les résultats de façon infalsifiable

Tu veux enregistrer sur ton site que quelqu'un a réussi le quiz – par exemple pour valider une leçon ou attribuer des points ? Fais alors confirmer le résultat par Qwissit. Ainsi, personne ne peut le simuler.

Comment ça marche

  1. Ta page donne au quiz un code à usage unique et le garde en mémoire.
  2. Le visiteur résout le quiz. Qwissit vérifie lui-même chaque réponse ; les questions ratées reviennent jusqu'à ce que tout soit juste.
  3. À la fin, ta page reçoit une preuve que seul Qwissit peut délivrer et l'envoie à ton serveur.
  4. Ton serveur demande à Qwissit si la preuve est authentique et correspond à ton code et à ton quiz. Seulement alors, il enregistre le résultat.

Ce que tu ajoutes

Deux endroits, tous deux en PHP. Tes visiteurs doivent être connectés (session), car le résultat doit appartenir à quelqu'un.

A) Sur la page du quiz : Ce bloc remplace l'extrait normal. Adapte data-set et data-course à ton quiz – les valeurs figurent dans le code ci-dessus.

<?php
session_start();   // your visitors are signed in
$nonce = $_SESSION['quiz_nonce']['http'] ??= rtrim(strtr(base64_encode(random_bytes(16)), '+/', '-_'), '=');
?>
<div id="quiz" data-qwissit-widget data-set="12" data-course="13" data-lang="de"
     data-verify="<?= $nonce ?>"></div>
<script src="https://www.qwissit.com/widget/v1/qwissit-widget.js" async></script>
<script>
document.getElementById('quiz').addEventListener('qwissit:finish', function (e) {
  if (!e.detail.passed || !e.detail.token) return;
  fetch('quiz-complete.php', {
    method: 'POST',
    credentials: 'same-origin',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: 'lesson=http&token=' + encodeURIComponent(e.detail.token)
  }).then(function (r) {
    if (r.ok) { /* done: e.g. show a tick */ }
  });
});
</script>

B) Un nouveau fichier quiz-complete.php dans le même dossier. Indique dans QUIZZES les mêmes valeurs pour set et course et enregistre le résultat à la ligne marquée, comme il convient à ton site.

<?php
// quiz-complete.php – checks the result with Qwissit and saves it only if everything matches
session_start();
const QUIZZES = ['http' => ['set' => 12, 'course' => 13]];   // same values as data-set / data-course

$lesson = (string)($_POST['lesson'] ?? '');
$token = (string)($_POST['token'] ?? '');
$quiz = QUIZZES[$lesson] ?? null;
$nonce = (string)($_SESSION['quiz_nonce'][$lesson] ?? '');
if (!$quiz || $nonce === '' || $token === '') { http_response_code(400); exit; }

$ch = curl_init('https://www.qwissit.com/widget/v1/verify');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => http_build_query(['token' => $token]),
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 4,
]);
$r = json_decode((string)curl_exec($ch), true);
curl_close($ch);

if (!is_array($r)) { http_response_code(503); exit; }   // Qwissit not reachable: save nothing
if (($r['valid'] ?? false) !== true
    || !hash_equals($nonce, (string)($r['nonce'] ?? ''))
    || (int)$r['set'] !== $quiz['set'] || (int)$r['course'] !== $quiz['course']) {
    http_response_code(403); exit;                       // forged, already used, expired or another quiz
}
unset($_SESSION['quiz_nonce'][$lesson]);                 // the code counts only once

// ▶ save the result here, e.g. user + $lesson + date (+ $r['wrong'] = failed attempts)

header('Content-Type: application/json');
echo json_encode(['ok' => true]);

Le fichier n'enregistre que si Qwissit confirme la preuve, qu'elle correspond à ton code à usage unique et qu'elle vient du bon quiz. Ensuite, le code est épuisé : chaque résultat ne compte qu'une fois. Si Qwissit est injoignable pour le moment, rien n'est enregistré – laisse le visiteur réessayer plus tard. La preuve est valable une heure.

Bon à savoir

Texte pour ta politique de confidentialité

Une proposition à adapter à ton site. Elle ne remplace pas un conseil juridique.

Intégré directement

Via ton propre domaine (proxy)

Certifications & examens

Quel examen pour la suite ?

Tu peux déjà t’entraîner pour 19 examens, 21 sont soumis au vote. Découvre toutes les certifications avec les infos officielles, vote ou propose ton examen.

Voir toutes les certifications