Aperçu
Code d'intégration
Colle le code à l'endroit de ta page où le quiz doit apparaître.
Bon à savoir
- Si ton site utilise une Content Security Policy, ajoute dans script-src : https://www.qwissit.com
- Le widget ne dépose aucun cookie et n'enregistre rien dans le navigateur. Il charge uniquement le script et les questions depuis Qwissit.
- Les questions changent automatiquement. Pour modifier les couleurs ou les textes, génère ici un nouveau code et remplace l'ancien.
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.
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
- Ta page donne au quiz un code à usage unique et le garde en mémoire.
- 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.
- À la fin, ta page reçoit une preuve que seul Qwissit peut délivrer et l'envoie à ton serveur.
- 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
- Pourquoi ce détour par ton serveur ? Le widget signale aussi la fin du quiz directement dans le navigateur (événement qwissit:finish), mais n'importe qui avec quelques connaissances techniques peut le déclencher lui-même. Cela suffit pour un affichage, pas pour des points, des certificats ou des déblocages.
- N'affiche le quiz avec code qu'aux visiteurs connectés et ne crée pas de session pour les autres – sinon chaque robot en crée une.
- Protège quiz-complete.php comme tes autres formulaires : vérifie la connexion, n'accepte que les requêtes de ton propre site, limite le nombre de requêtes.
- Après une réussite, le visiteur reçoit un nouveau code à la visite suivante et peut refaire le quiz.
- Pour tester : une preuve inventée, la même preuve une deuxième fois et la preuve d'un autre quiz doivent toutes être refusées.
Texte pour ta politique de confidentialité
Une proposition à adapter à ton site. Elle ne remplace pas un conseil juridique.
Intégré directement
Sur ce site, nous intégrons un quiz de Qwissit (www.qwissit.com). Au chargement, ton navigateur récupère le script et les questions sur www.qwissit.com ; ton adresse IP est alors transmise. Le quiz ne dépose aucun cookie, n'enregistre rien dans ton navigateur et ne conserve pas tes réponses. La base juridique est notre intérêt légitime à proposer un contenu d'apprentissage interactif (art. 6, par. 1, point f, RGPD). En savoir plus : https://www.qwissit.com/en/privacy#widget
Via ton propre domaine (proxy)
Sur ce site, nous intégrons un quiz de Qwissit. Notre propre serveur livre le script et les questions, qu'il récupère chez Qwissit. Ton navigateur ne se connecte pas à Qwissit, et Qwissit ne reçoit ni ton adresse IP, ni cookies, ni autres données te concernant. Le quiz ne dépose aucun cookie, n'enregistre rien dans ton navigateur et ne conserve pas tes réponses. En savoir plus : https://www.qwissit.com/en/privacy#widget