Veb saytınıza "Tamga ilə daxil ol" əlavə etmək
Bu bələdçi veb saytına şəbəkənin qaydalarına uyğun rəqəmsal cüzdanla (məs. Tamga Wallet) qeydiyyat və giriş əlavə etmək istəyən tərtibatçılar üçündür. Yoxlamanı Tamga-nın hostinq edilən yoxlayan tərəfi (verifier)Təqdim edilən rəqəmsal sənədi yoxlayan tərəf: imza, etibar siyahısındakı sənədi verən qurum, status və siyasət. Yoxlayan tərəf olaraq da adlandırılır. Tamga Verify həyata keçirir; Sizə bir səhifə dəsti və bir neçə server uc nöqtəsi qalır.
Nə vaxt oxunmalı: saytınıza parolsuz, telefonla qeydiyyat və giriş əlavə etmək istədiyiniz zaman. Əvvəlcə GUIDE-0000 ilə tanış olun. Yoxlamanı tamamilə öz serverinizdə aparmaq istəsəniz, GUIDE-0002 bölməsinə keçin.
Sınamaq üçün: işlək nümunə sayt test şəbəkəsindədir: https://verify.sandbox.tamga.network/sample-site (sandbox istifadəyə verildikdə; ünvanlar və test rəqəmsal cüzdanının ayarı GUIDE-0013 bölməsindədir). Real şəbəkədəki Tamga Verify-da nümunə sayt yoxdur.
Necə işləyir?
- Qeydiyyat (bir dəfə). Saytınız siyasət ilə sorğu başladır (məs. "ad, soyad" + psevdonim (pseudonym)Rəqəmsal cüzdanın hər vebsayt üçün ayrıca törətdiyi sabit hesab identifikatoru; iki sayt eyni şəxsi əlaqələndirə bilmir.). Kompüterdə QR, telefonda "Rəqəmsal cüzdanında aç" düyməsi görünür. Şəxs rəqəmsal cüzdanda yalnız bu sahələri və "bu sayta xas psevdonim" sətrini görür və təsdiqləyir.
- Yoxlama. Yoxlayan tərəf rəqəmsal sənədi (credential)Sənədi verən qurum tərəfindən imzalanan və şəxsin rəqəmsal cüzdanında saxlanan rəqəmsal sənəd; şəxs yalnız soruşulan sahələri göstərir. yoxlayır: imza, etibar siyahısı (trust list)Bir ölkənin kök sertifikatlarının, sənədi verən qurumlarının və qeydiyyatlı yoxlayan tərəflərinin imzalanmış siyahısı. Bu gün Tamga-da etibar bu siyahılara əsaslanır; ortaq jurnal (ledger) sonra gələcək., ləğv (revocation)Müddəti bitmədən əvvəl rəqəmsal sənədin geri çəkilməsi; sənədi verən qurum bunu yoxlayan tərəflərin yoxladığı status siyahısında qeyd edir., holder bindingRəqəmsal sənədi yalnız sənəd sahibinin cihazında olan bir açara bağlamaq, beləliklə kopyalanmış sənəd təqdim edilə bilməz.. Səhifəniz nəticəni izləyir;
ACCEPTEDolduqda təqdimat identifikatorunu (presentation_id) öz serverinizə göndərir. Serveriniz təsdiqlənmiş sahələri yoxlayan tərəfdən alır, hesabı açır və sessiya kukisi verir. - Passkey (tövsiyə olunur). Qeydiyyatdan dərhal sonra "Bu cihaza passkey əlavə et". Növbəti girişlər Face ID və ya barmaq izi ilə olur: rəqəmsal cüzdan açılmır, heç bir sahə paylaşılmır, passkey yalnız Sizin saytınıza xasdır.
- Yeni cihaz və ya passkey yoxdur. "Tamga ilə daxil ol" yalnız psevdonimi istəyir, heç bir rəqəmsal sənəd sahəsini istəmir; sonra yenə passkey əlavə edilir.
Hesab açarı psevdonimdir (ADR-0031). Psevdonim yalnız Sizin sayta, yəni yoxlayan tərəf kimi Sizə məxsusdur: başqa sayt eyni şəxs üçün başqa bir dəyər görür, saytlar şəxsləri bir-biri ilə əlaqələndirə bilməz. Şəxs yeni telefonda şəxsiyyətini yenidən təsdiqlədikdə eyni psevdonim geri qayıdır; hesab itmir.
1. Server: təqdimatı Siz açırsınız
Hostinq edilən yoxlayan tərəfə etdiyiniz hər çağırış qısamüddətli, imzalı bəyan daşıyır (Authorization: Bearer …, ən çoxu 60 saniyə, birdəfəlik). Bəyanı saytınızın etibar siyahısındakı qeydində yer alan əlçatanlıq sertifikatının (access certificate)Yoxlayan tərəfin öz sorğularını imzaladığı X.509 sertifikatı; onun müştəri identifikatoru bu sertifikatın heşindən alınır. açarı ilə imzalayırsınız; ayrıca parol yoxdur (ADR-0017).
import { createRpAssertion, pemRpSigner } from "@tamga-network/verifier";
const rp = await pemRpSigner(RP_KEY_PEM, RP_CERT_PEM); // client_id = x509_hash (from the certificate)
const auth = async () => ({ authorization: `Bearer ${await createRpAssertion(rp, VERIFIER)}` });
// POST /tamga/start { policy } → to the page: { presentation_id, qr_payload, expires_at, status_token }
const r = await fetch(`${VERIFIER}/presentations`, { method: "POST",
headers: { ...(await auth()), "content-type": "application/json", accept: "application/json" },
body: JSON.stringify({ policy_id: policy }) }).then((x) => x.json());Müştəri identifikatoru (x509_hashHAIP-dən bir müştəri identifikator sxemi: identifikator yoxlayan tərəfin giriş sertifikatının base64url SHA-256 heşidir.) sertifikatınızdan hesablanır. Psevdonim isə saytınızın qeydiyyatdakı domen adına bağlıdır; sertifikatı yeniləsəniz də dəyişmir (ADR-0034).
Rəqəmsal cüzdanın təsdiq ekranında saytınızın qeydiyyatdakı adı görünür ("vasitəçi yoxlayan tərəf: verify.tamga.network" qeydi ilə). İstədiyiniz sahələr qeydiyyatınızın əhatə dairəsinə görə yoxlanılır.
2. Səhifə
Yoxlayan tərəf səhifə dəstini hazır təqdim edir; <script> ilə əlavə edin:
<script src="https://verify.tamga.network/tamga-verifier.js"></script>
<div id="tamga"></div>
<script>
TamgaVerifier.mount(document.getElementById("tamga"), {
verifier: "https://verify.tamga.network",
policy: "site-signup", // "site-signin" for sign-in
start: () => fetch("/tamga/start", { method: "POST", headers: { "content-type": "application/json" },
body: JSON.stringify({ policy: "site-signup" }) }).then((r) => r.json()),
onResult: (presentationId) =>
fetch("/oturum", { method: "POST", headers: { "content-type": "application/json" },
body: JSON.stringify({ presentation_id: presentationId }) }).then(() => location.reload()),
});
</script>npm ilə eyni interfeys: import { mount, passkey } from "@tamga-network/verifier/web".
Dəst yoxlama aparmır və dəyərləri görmür: yalnız status_token ilə vəziyyəti izləyir; qərar və dəyərlər serverinizdədir. onError INDETERMINATE vəziyyətini ayrıca göstərir: "hazırda yoxlamaq mümkün olmadı, yenidən cəhd edin" — bu, rəqəmsal sənədin etibarsız olduğu anlamına gəlmir.
3. Server: sessiyanın açılması
// POST /oturum { presentation_id } — accept JSON only (CSRF); Origin must be the same site
const r = await fetch(`${VERIFIER}/presentations/${id}`, { headers: await auth() }).then((x) => x.json());
if (r.outcome !== "ACCEPTED") return res.status(400).send(); // INDETERMINATE → "try again"
const { claims } = await fetch(`${VERIFIER}/presentations/${id}/claims`, { headers: await auth() }).then((x) => x.json());
// the values are given ONCE (a second read returns 410) and are deleted 5 min after the result — process them at once
const hesapAnahtari = hmacSha256(SITE_SIRRI, claims.pseudonym); // the pseudonym is yours alone; still store it keyed with a site secretNəticəni və dəyərləri yalnız təqdimatı açan sayt ala bilər; təqdimat identifikatorunu bilən başqa biri 404 alır.
Nümunə saytda tətbiq olunmuş formada (apps/verify/src/routes/site.ts) diqqət yetirilməli məqamlar:
- Birdəfəlik istifadə: bir təqdimat yalnız bir sessiya açır.
- Siyasət yoxlaması: yalnız öz sayt siyasətlərinizlə edilmiş təqdimatı qəbul edin.
- Hesab açarı:
claims.pseudonym. Yoxlayan tərəf imzanı,aud/nonceBir dəfə istifadə olunan təsadüfi dəyər; yoxlayan tərəf onu göndərir, rəqəmsal cüzdan isə imzalayır, beləliklə köhnə təqdimetmə təkrarlana bilməz. dəyərlərini və WIA (Wallet Instance Attestation)Cüzdan provayderinin imzaladığı, bir cüzdan quraşdırılmasının həqiqi olduğunu bildirən qısaömürlü bəyanat; sənədi verən qurumlar verilmədən əvvəl bunu yoxlayır. sübutunu artıq yoxlamışdır. Şəxsiyyət sənədinin heşi və ya şəxsiyyət nömrəsi sayt siyasətlərində tələb olunmur. Defolt olaraq hər şəxs üçün bir psevdonim (bir hesab) var; qeydiyyatınızpseudonyms: "multiple"olduqda şəxs bir neçə psevdonim aça bilər. "Hər şəxs üçün bir hesab" məhdudiyyəti real rəqəmsal cüzdana əsaslanır: WIA bunu məhdudlaşdırır, qəti sübut sıfır bilikli sübut vasitəsilə gələcək. - Kuki:
HttpOnly; SameSite=Lax; Secure; müddəti server tərəfində saxlayın; CSRF üçün yalnız JSON + Origin yoxlaması. - Fərdi məlumatlar loqlanmır (ad, açar, passkey identifikatoru daxil olmaqla).
4. Passkey (WebAuthn)
Server tərəfi üçün WebAuthn kitabxanasından istifadə edin (nümunə saytda @simplewebauthn/server): qeydiyyat və giriş üçün options + verify uc nöqtələri; attestation: "none", residentKey: "required", userVerification: "required". Səhifə tərəfi:
const o = await post("/passkey/register/options"); // while signed in
await post("/passkey/register/verify", await TamgaVerifier.passkey.create(o));
// sign-in: const { flow, options } = await post("/passkey/login/options");
// await post("/passkey/login/verify", { flow, response: await TamgaVerifier.passkey.get(options) });WebAuthn IP ünvanında işləmir: localhost və ya HTTPS domen adı lazımdır (rpID = səhifənin domen adı).
5. İstismara verməzdən əvvəl
- Saytınız Tamga etibar siyahısında yoxlayan tərəf qeydi tələb edir; istədiyiniz sahələr qeydin əhatə dairəsini aşa bilməz.
- Hostinq edilən yoxlayan tərəf real şəbəkədə və sandbox-da bəyansız sorğunu rədd edir (
TAMGA_VERIFY_REQUIRE_RP_AUTH=1). Yalnız lokal inkişaf (demo/LAN) rejimində bəyansız köhnə yolDeprecationbaşlığı ilə işləyir. İstəsəniz, yoxlamanı tamamilə öz serverinizdə aparın: GUIDE-0002. - Siyasət adları və sahə dəstləri Tamga ilə birlikdə müəyyən edilir (məs. yalnız "18 yaşdan yuxarı" →
age-over-18-mdoc).
Qaydalar
Bu bələdçidəki davranışların əsaslandığı qaydalar:
| Kod | Nə deyir |
|---|---|
| SPEC-API-0001 AP6 | sorğu yoxlayan tərəf qeydinin əhatə dairəsini aşa bilməz |
| ADR-0017 HV1–HV4 | nəticə və dəyərlər yalnız təqdimatı açan sayta, bir dəfə verilir |
| ADR-0017 HV6 | vasitəçi yoxlayan tərəfdə ekranda və əhatə dairəsində əsl sayt əsas götürülür |
| SPEC-API-0001 P1 addımı | yoxlayan tərəf psevdonim imzasını, aud/nonce dəyərlərini və WIA-nı yoxlayır |
| ADR-0031 PS4 | sayt giriş siyasətləri şəxsiyyət nömrəsini və ya şəxsiyyət sənədinin heşini tələb etmir |