Altcha
Alternativă open-source echivalentă cu reCaptcha.
Introducere
Implementarea mecanismului de securitate cu captcha este de o importanță extremă; iată câteva motive relevante:
- Pentru a împiedica roboții să facă accesări automate ale adreselor API.
- Pentru a garanta că accesul este făcut de o persoană reală.
- De asemenea, garantează că accesul a fost făcut cu un browser.
Mult timp, mecanismul captcha oferea o provocare pe care utilizatorul trebuia să o completeze.
În zilele noastre acest lucru este inutil, deoarece se folosește un mecanism de chei criptate combinat cu o provocare care trebuie rezolvată de un algoritm ce utilizează interacțiunea din browser, detectând astfel dacă este o interacțiune umană sau robotizată.
Această metodă este ingenioasă și fiabilă; cu un singur click se detectează dacă este uman sau robot.
Altcha este un proiect open-source care implementează acest proces de securitate, cu un widget de frontend care se integrează și cu React, și cu o resursă de backend oferită de Netuno.
Limitări
Altcha utilizează Web Crypto API, funcționează doar pe adrese HTTPS securizate cu certificat SSL sau local.
În frontend, dacă domeniul nu este
localhost, URL-ul trebuie obligatoriu să fie HTTPS securizat cu certificat SSL.
Când frontend-ul este accesat local, browserele permit utilizarea Web Crypto API doar la adresa locală, obligatoriu localhost, altfel este necesar HTTPS securizat cu certificat SSL.
Backoffice
Pentru a activa autentificarea cu Altcha în backoffice-ul aplicației tale Netuno, folosește următoarea configurație în aplicație:
{
...
"auth": {
"altcha": {
"admin": {
"enabled": true
}
}
},
...
}
Gata, acum trebuie doar să accesezi ecranul de autentificare al backoffice-ului și vei vedea checkbox-ul Altcha funcționând perfect.
Cum funcționează
Netuno oferă în API-ul REST un serviciu standard care furnizează parametrii Altcha pentru frontend; de obicei, adresa acestui serviciu este:
http://localhost:9000/services/_altcha
Cu acești parametri, widget-ul Altcha din frontend generează rezultatul provocării semnat digital, care este trimis către backend în câmpul ascuns altcha al formularului.
În backend se validează dacă rezultatul și semnătura digitală sunt într-adevăr corecte.
Widget în HTML
Exemplu de integrare a widget-ului în HTML-ul de autentificare al backoffice-ului:
<script type="text/javascript" src="/scripts/plugins/altcha/altcha.i18n.umd.min.cjs"></script>
<form ...>
<input id="inputAltcha" type="hidden" name="altcha" value="">
<altcha-widget id="widgetAltcha"
challenge="/services/_altcha" language="ro"
hideLogo hideFooter></altcha-widget>
<script>
document.getElementById("widgetAltcha").addEventListener("statechange", function (e) {
if (e.detail.state === "verified") {
document.getElementById("inputAltcha").value = e.detail.payload;
}
}, false);
</script>
...
</form>
Observați că URL-ul folosit în atributul challenge al widget-ului este serviciul generat automat de Netuno cu parametrizarea provocării.
Autentificare externă
Autentificarea implementată în mod normal și sigură cu JWT folosește serviciul standard al API-ului REST pentru autentificare, care de obicei este:
http://localhost:9000/services/_auth
Acest serviciu generat automat de Netuno permite garantarea securității pentru autentificarea externă cu JWT nativ, dar face și validarea rezultatului provocării widget-ului captcha.
Pentru a activa Altcha în autentificare, adaugă configurația:
{
...
"auth": {
"altcha": {
"enabled": true
}
},
...
}
Astfel, doar cererile de autentificare, adică autentificările care trimit cheia rezultatului provocării generat de Altcha și care este validă, vor putea reuși; altfel, autentificarea va fi blocată.
În frontend trebuie integrat widget-ul Altcha și trimisă cheia rezultatului provocării în câmpul
altcha.
Widget în React
Mai jos vedeți cum să integrați widget-ul în React:
Adăugați dependența Altcha:
bun add altcha
Importați Altcha în cod:
import "altcha/i18n";
Creați starea pentru stocarea cheii rezultatului provocării:
const [payloadAltcha, setPayloadAltcha] = useState(null);
Creați o referință internă în componenta React pentru widget:
const altcha = useRef(null);
Adăugați efectul de încărcare a componentei care utilizează referința widget-ului, cu evenimentul care observă când este bifată caseta widget-ului pentru a încărca cheia rezultatului provocării în stare:
useEffect(() => {
if (altcha && altcha.current) {
function altchaVerificat(ev) {
if (ev.detail.state === "verified") {
setPayloadAltcha(ev.detail.payload);
}
}
altcha.current.addEventListener("statechange", altchaVerificat, false);
return () => {
if (altcha.current != null) {
altcha.current.removeEventListener("statechange", altchaVerificat, false);
}
}
}
}, [altcha]);
Exemplu al widget-ului în "HTML"-ul componentei React:
<altcha-widget
ref={altcha}
challenge={_service.url('/_altcha')}
language="ro"
delay={1}
hideLogo={true}
hideFooter={true}
></altcha-widget>
Auth Client
Vedeți cum să integrați Altcha în Auth Client.
Folosiți codul de mai jos în evenimentul care trimite datele formularului de autentificare către backend, cum ar fi evenimentele onSubmit, onClick sau onFinish ale formularelor Ant.Design:
_auth.login({
username,
password,
data: (data) => {
data.altcha = payloadAltcha;
return data;
},
success: ({json}) => {
...
},
fail: (data) => {
...
}
});
Observați că payloadAltcha este starea care conține cheia rezultatului provocării captcha.
Exemplu complet în pagina de autentificare a ReAuthKit:
Integrare în servicii
Pe lângă autentificarea prezentată mai sus, mecanismul captcha cu Altcha poate fi integrat în orice alt tip de serviciu.
Se recomandă integrarea captcha în orice serviciu public care poate fi țintă de atacuri, cum ar fi automatizarea exhaustivă a roboților pentru înregistrarea masivă de date.
În frontend, în ecranul în care este integrat serviciul API REST trebuie implementat și widget-ul de securitate Altcha; adică, acolo unde este apelat serviciul trebuie folosit widget-ul.
Service Client
În continuare vedeți cum să integrați Altcha în Service Client.
Integrarea widget-ului în frontend este similară cu cea explicată mai sus în:
Trebuie să obținem payload-ul widget-ului exact ca în exemplul de mai sus; procesul este același ca la autentificarea prin login.
Payload-ul este trimis către backend printr-un parametru în URL, un câmp de formular sau chiar ca proprietate în JSON, în funcție de metoda HTTP și de modul în care este implementat serviciul.
Exemplu de trimitere a payload-ului către serviciul de înregistrare, sau creare a unui cont nou de utilizator:
_service({
method: 'POST',
url: 'register',
data: {
name,
email,
password,
altcha: payloadAltcha
},
success: (response) => {
...
},
fail: (e) => {
...
}
});
Observați că payloadAltcha este starea care conține cheia rezultatului provocării captcha.
Exemplu complet în pagina de înregistrare a ReAuthKit:
Backend
Cu payload-ul trimis către serviciul API REST, în codul serviciului, pe partea de backend, trebuie să îl validăm; vedeți cum:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
const payloadAltcha = _req.getString("altcha");
if (_auth.altchaEnabled() && !_altcha.verifySolution(payloadAltcha)) {
_header.status(409);
_out.json(
_val.map()
.set("error", "invalid-altcha-payload")
);
_exec.stop();
}
const payloadAltcha = _req.getString("altcha");
if (_auth.altchaEnabled() && !_altcha.verifySolution(payloadAltcha)) {
_header.status(409);
_out.json(
_val.map()
.set("error", "invalid-altcha-payload")
);
_exec.stop();
}
payloadAltcha = _req.getString("altcha")
if _auth.altchaEnabled() and _altcha.verifySolution(payloadAltcha) == False:
_header.status(409)
_out.json(
_val.map()
.set("error", "invalid-altcha-payload")
)
_exec.stop()
payloadAltcha = _req.getString("altcha")
if _auth.altchaEnabled() and _altcha.verifySolution(payloadAltcha) == false
_header.status(409)
_out.json(
_val.map()
.set("error", "invalid-altcha-payload")
)
_exec.stop()
end
val payloadAltcha = _req.getString("altcha")
if (_auth.altchaEnabled() && !_altcha.verifySolution(payloadAltcha)) {
_header.status(409)
_out.json(
_val.map()
.set("error", "invalid-altcha-payload")
)
_exec.stop()
}
final payloadAltcha = _req.getString("altcha")
if (_auth.altchaEnabled() && !_altcha.verifySolution(payloadAltcha)) {
_header.status(409)
_out.json(
_val.map()
.set("error", "invalid-altcha-payload")
)
_exec.stop()
}
Exemplu complet al serviciului de înregistrare ReAuthKit:
Vedeți mai multe despre resursele de programare low-code și poliglotă:
Concluzie
Într-un mod destul de simplificat, putem crea un mecanism de securitate în serviciile API pentru a evita roboții și a garanta interacțiunea umană în browser.
Se recomandă utilizarea mecanismului captcha cu Altcha în serviciile publice cele mai sensibile, cum ar fi serviciile de înregistrare și autentificare.
Cu implementarea nativă oferită de Netuno, devine foarte simplu să activați și să utilizați acest mecanism în orice serviciu API REST.
Se recomandă ca backoffice-ul generat automat de Netuno să aibă întotdeauna autentificarea cu Altcha activată în producție și să folosească HTTPS cu certificat SSL.
Ori de câte ori este posibil, utilizați Altcha pentru a garanta securitate și robustețe serviciilor publice ale API-ului.