Altcha
Alternative open-source équivalente à reCaptcha.
Introduction
La mise en œuvre du mécanisme de sécurité avec captcha est extrêmement importante, voici quelques raisons pertinentes :
- Éviter que les robots effectuent des accès automatiques aux adresses de l’API.
- Garantir que l’accès est effectué par une personne réelle.
- Garantit également que l’accès a été effectué avec un navigateur.
Pendant longtemps, le mécanisme de captcha proposait un défi que l’utilisateur devait remplir.
Aujourd’hui, cela est inutile, car un mécanisme de clés chiffrées combiné à un défi est utilisé ; ce défi doit être résolu par un algorithme qui s’appuie sur l’interaction dans le navigateur, ce qui permet de détecter s’il s’agit d’une interaction humaine ou robotisée.
Cette méthode est ingénieuse et fiable : avec un seul clic, il est détecté s’il s’agit d’un humain ou d’un robot.
Le Altcha est un projet open-source qui implémente ce processus de sécurité, avec un widget frontend qui s’intègre également à React, et une fonctionnalité backend que Netuno offre.
Limitations
Le Altcha utilise la Web Crypto API, il ne fonctionne que sur des adresses HTTPS sécurisées avec certificat SSL, ou localement.
Dans le frontend, si le domaine n’est pas
localhost, l’URL doit obligatoirement être HTTPS sécurisée avec certificat SSL.
Lorsque le frontend est accédé localement, les navigateurs permettent d’utiliser la Web Crypto API uniquement sur l’adresse locale, obligatoirement localhost ; sinon, HTTPS sécurisé avec certificat SSL est requis.
Back-office
Pour activer l’authentification avec Altcha dans le back-office de votre application Netuno, utilisez la configuration suivante dans l’application :
{
...
"auth": {
"altcha": {
"admin": {
"enabled": true
}
}
},
...
}
Voilà, il suffit maintenant d’accéder à l’écran de connexion du back-office et vous verrez la case à cocher d’Altcha pleinement fonctionnelle.
Comment ça fonctionne
Netuno fournit dans l’API REST un service standard qui fournit les paramètres d’Altcha au frontend ; normalement, l’adresse de ce service est :
http://localhost:9000/services/_altcha
Avec les paramètres, le widget Altcha dans le frontend génère le résultat du défi signé numériquement, qui est envoyé au backend dans le champ caché altcha du formulaire.
Dans le backend, il est validé si le résultat et la signature numérique sont réellement corrects.
Widget en HTML
Exemple d’intégration du widget dans le HTML de connexion du back-office :
<script type="text/javascript" src="/scripts/plugins/altcha/altcha.i18n.umd.min.cjs"></script>
<form ...>
<input id="champAltcha" type="hidden" name="altcha" value="">
<altcha-widget id="widgetAltcha"
challenge="/services/_altcha" language="fr"
hideLogo hideFooter></altcha-widget>
<script>
document.getElementById("widgetAltcha").addEventListener("statechange", function (evenement) {
if (evenement.detail.state === "verified") {
document.getElementById("champAltcha").value = evenement.detail.payload;
}
}, false);
</script>
...
</form>
Remarquez que l’URL utilisée dans l’attribut challenge du widget est le service auto-généré par Netuno avec le paramétrage du défi.
Authentification externe
L’authentification normalement implémentée et sécurisée avec JWT utilise le service standard de l’API REST pour l’authentification, qui est habituellement :
http://localhost:9000/services/_auth
Ce service auto-généré par Netuno permet de garantir la sécurité pour l’authentification externe avec JWT natif, mais effectue aussi la validation du résultat du défi du widget de captcha.
Pour activer Altcha dans l’authentification, ajoutez la configuration :
{
...
"auth": {
"altcha": {
"enabled": true
}
},
...
}
Ainsi, seules les demandes d’authentification, c’est-à-dire les connexions qui envoient la clé du résultat du défi généré par Altcha et qui est valide, pourront s’authentifier avec succès ; sinon, la connexion sera bloquée.
Le widget d’Altcha doit être intégré dans le frontend et envoyer la clé du résultat du défi dans le champ
altcha.
Widget dans React
Voyez ci-dessous comment intégrer le widget dans React :
Ajoutez la dépendance d’Altcha :
bun add altcha
Importez Altcha dans le code :
import "altcha/i18n";
Créez l’état pour stocker la clé du résultat du défi :
const [chargeAltcha, setChargeAltcha] = useState(null);
Créez une référence interne dans le composant React pour le widget :
const referenceAltcha = useRef(null);
Ajoutez l’effet de chargement du composant qui utilise la référence du widget, avec un événement qui observe quand la case à cocher du widget est cliquée pour charger la clé du résultat du défi dans l’état :
useEffect(() => {
if (referenceAltcha && referenceAltcha.current) {
function altchaValide(evenement) {
if (evenement.detail.state === "verified") {
setChargeAltcha(evenement.detail.payload);
}
}
referenceAltcha.current.addEventListener("statechange", altchaValide, false);
return () => {
if (referenceAltcha.current != null) {
referenceAltcha.current.removeEventListener("statechange", altchaValide, false);
}
}
}
}, [referenceAltcha]);
Exemple du widget dans le « HTML » du composant React :
<altcha-widget
ref={referenceAltcha}
challenge={_service.url('/_altcha')}
language="fr"
delay={1}
hideLogo={true}
hideFooter={true}
></altcha-widget>
Client d’authentification
Voyez comment intégrer Altcha dans le Client d’authentification.
Utilisez le code ci-dessous dans l’événement qui envoie les données du formulaire de connexion au backend, comme les événements onSubmit, onClick, ou onFinish des formulaires Ant.Design :
_auth.login({
username,
password,
data: (donnees) => {
donnees.altcha = chargeAltcha;
return donnees;
},
success: ({json}) => {
...
},
fail: (erreur) => {
...
}
});
Remarquez que chargeAltcha est l’état qui contient la clé du résultat du défi du captcha.
Exemple complet dans la page de connexion de ReAuthKit :
Intégration dans les services
Outre l’authentification comme vu ci-dessus, dans tout autre type de service, le mécanisme de captcha avec Altcha peut être intégré.
Il est recommandé d’intégrer le captcha dans tout service public susceptible d’être la cible d’attaques, comme l’automatisation exhaustive par des robots pour l’enregistrement massif de données.
Dans le frontend, sur l’écran où le service de l’API REST est intégré, le widget de sécurité d’Altcha doit également être implémenté ; c’est-à-dire que là où le service est appelé, le widget doit être utilisé.
Client de service
Voyez ci-après comment intégrer Altcha dans le Client de service.
L’intégration du widget dans le frontend est similaire à ce qui a déjà été expliqué ci-dessus dans :
Nous devons obtenir la charge utile du widget, exactement comme déjà illustré ci-dessus ; cela suit le même processus que l’authentification de connexion.
La charge utile est envoyée au backend via un paramètre dans l’URL, un champ de formulaire, ou encore comme une propriété dans le JSON ; cela dépend de la méthode HTTP et de la manière dont le service est implémenté.
Exemple d’envoi de la charge utile au service d’inscription, ou de création d’un nouveau compte utilisateur :
_service({
method: 'POST',
url: 'inscription',
data: {
nom,
email,
motDePasse,
altcha: chargeAltcha
},
success: (reponse) => {
...
},
fail: (erreur) => {
...
}
});
Remarquez que chargeAltcha est l’état qui contient la clé du résultat du défi du captcha.
Exemple complet dans la page d’inscription de ReAuthKit :
Backend
Avec la charge utile envoyée au service de l’API REST, alors dans le code du service, côté backend, nous devons la valider, voyez comment :
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const chargeAltcha = _req.getString("altcha");
if (_auth.altchaEnabled() && !_altcha.verifySolution(chargeAltcha)) {
_header.status(409);
_out.json(
_val.map()
.set("error", "charge-altcha-invalide")
);
_exec.stop();
}
const chargeAltcha = _req.getString("altcha");
if (_auth.altchaEnabled() && !_altcha.verifySolution(chargeAltcha)) {
_header.status(409);
_out.json(
_val.map()
.set("error", "charge-altcha-invalide")
);
_exec.stop();
}
chargeAltcha = _req.getString("altcha")
if _auth.altchaEnabled() and _altcha.verifySolution(chargeAltcha) == False:
_header.status(409)
_out.json(
_val.map()
.set("error", "charge-altcha-invalide")
)
_exec.stop()
chargeAltcha = _req.getString("altcha")
if _auth.altchaEnabled() and _altcha.verifySolution(chargeAltcha) == false
_header.status(409)
_out.json(
_val.map()
.set("error", "charge-altcha-invalide")
)
_exec.stop()
end
val chargeAltcha = _req.getString("altcha")
if (_auth.altchaEnabled() && !_altcha.verifySolution(chargeAltcha)) {
_header.status(409)
_out.json(
_val.map()
.set("error", "charge-altcha-invalide")
)
_exec.stop()
}
final chargeAltcha = _req.getString("altcha")
if (_auth.altchaEnabled() && !_altcha.verifySolution(chargeAltcha)) {
_header.status(409)
_out.json(
_val.map()
.set("error", "charge-altcha-invalide")
)
_exec.stop()
}
Exemple complet du service d’inscription de ReAuthKit :
Voir plus sur les fonctionnalités de programmation low-code et polyglotte :
Conclusion
De manière assez simplifiée, nous pouvons créer un mécanisme de sécurité dans les services de l’API pour éviter les robots et garantir l’interaction par des humains dans le navigateur.
Il est recommandé d’utiliser le mécanisme de captcha avec Altcha dans les services publics les plus sensibles, comme les services d’inscription et d’authentification.
Avec l’implémentation native que Netuno offre, il devient très simple d’activer et d’utiliser ce mécanisme dans n’importe quel service de l’API REST.
Il est recommandé que le back-office auto-généré de Netuno ait toujours l’authentification avec Altcha activée en production, et avec HTTPS et certificat SSL.
Chaque fois que possible, utilisez Altcha pour garantir la sécurité et la robustesse des services publics de votre API.