Iegulstiet nozīmju verifikāciju savā vietnē (bez iframe, bez SDK)

Pievienojiet savai vietnei nelielu JavaScript fragmentu (vai servera puses fetch), kas verificē jebkuru Open Badge, izmantojot publisku JSON-LD galapunktu. Bez iframe, bez trešo pušu izsekotāja.

Nacho Coll Autors Atjaunināts 9 min lasīšanai
Pievienojiet savai vietnei nelielu JavaScript fragmentu (vai servera puses fetch), kas verificē jebkuru Open Badge, izmantojot publisku JSON-LD galapunktu. Bez iframe, bez trešo pušu izsekotāja.

Ja jūs izsniedzat akreditācijas datus, agrāk vai vēlāk kāds pajautās: „Kā es zinu, ka šī nozīme ir īsta?” Godīga atbilde nekad nedrīkst būt „uzticieties PNG failam”. Open Badge v2.0 to atrisina ar publisku, mašīnlasāmu verifikācijas galapunktu, un „Verificēts” logrīka pievienošana jūsu vietnei aizņem apmēram desmit koda rindiņu – bez iframe, bez trešās puses iegulšanas skripta un bez SDK.

Šis ieraksts precīzi parāda, kā izsaukt galapunktu un attēlot rezultātu — vienkāršā JavaScript, kā arī serverī Node un Python. Tas arī skaidro, ko verifikācija patiesībā pārbauda, kā galapunkts iekļaujas līdzās cilvēkiem paredzētajām lapām, ko badges.ninja platformā jau saņem saņēmēji, un kļūdas, kuru dēļ verifikācijas logrīks izskatās pabeigts, bet klusi neko neapliecina.

Ko „verificēts” patiesībā nozīmē

Open Badge v2.0 apgalvojums (assertion) ir JSON-LD dokuments ar fiksētu struktūru: pats apgalvojums (kurš to saņēma, kad), atsauce uz BadgeClass (kas tas ir, kurš nosaka kritērijus) un atsauce uz izdevēja profilu (kurš par to galvo). Kad jūs „verificējat” nozīmi, jūs patiesībā pārbaudāt trīs atsevišķas lietas:

  1. Vai apgalvojums pastāv un tiek atrisināts. Balvas ID ir īsts, nevis uzminēts vai viltots.
  2. Vai tas ir atsaukts. Izdevējs var nozīmi atsaukt pēc fakta — kļūdaini izsniegts akreditācijas dokuments, politikas pārkāpums, beidzies sertifikāts — un pareizam verificētājam tas jāparāda, nevis tikai jāapstiprina, ka ieraksts pastāv.
  3. Vai ķēde turas kopā. Apgalvojuma atsauces uz nozīmi un izdevēju patiešām tiek atrisinātas uz īstiem, savstarpēji atbilstošiem ierakstiem, nevis bāreņiem vai nesaderīgiem ID.

Logrīks, kas tikai pārbauda URL un meklē statusu 200, pilnībā palaiž garām 2. punktu. Atsaukts apgalvojums joprojām tiek atrisināts bez problēmām — tas vienkārši satur atsaukuma karodziņu saturā. Ja jūsu logrīks pārbauda tikai to, „vai pieprasījums izdevās”, atsaukts akreditācijas dokuments tiks attēlots kā verificēts, kas ir sliktāk nekā logrīka neesamība.

Publiskā cilvēkiem paredzētā lapa pret API galapunktu

Katra balva, kas izsniegta platformā https://badges.ninja, saņem publisku URL, ko saņēmēji var tieši kopīgot un kura apskatei nav nepieciešama reģistrēšanās:

Public credential page

Uz šo lapu lielākā daļa saņēmēju ievietos saiti no LinkedIn, CV vai e-pasta paraksta — tā ir veidota cilvēkiem, rāda nozīmes attēlu, izdevēju un izsniegšanas datumu, un tās darbībai no jums nekas nav vajadzīgs. Tālāk aprakstītais API galapunkts atgriež to pašu pamatā esošo apgalvojumu kā strukturētu JSON-LD, un tas ir vajadzīgs, kad veidojat savu lietotāja saskarni, nevis tikai norādāt uz mūsējo.

Galapunkts

GET https://api.badges.ninja/certify-badge/award/{guid}

Autentifikācijas galvene nav nepieciešama — tas ir apzināti publisks, jo Open Badges pamatideja ir tāda, ka ikviens (darba devējs, personāla atlases speciālists, licencēšanas komisija) var verificēt akreditācijas datus bez konta. Pilna līguma informācija, tostarp precīzi atgrieztā apgalvojuma lauku nosaukumi, ir verifikācijas dokumentācijā.

Padodiet balvas GUID, kas jums ir vai nu no jūsu pašu izsniegšanas ierakstiem, vai kuru izgūstat no saņēmēja kopīgotas saites badges.ninja/awards/<guid>.

Vienkāršs JS: fetch un attēlošana

Šis ir viss logrīks. Bez būvēšanas soļa, bez npm pakotnes — ievietojiet to tieši jebkurā lapā:

<div id="badge-verify"></div>
<script>
  async function renderBadgeVerification(awardId, mountId) {
    const el = document.getElementById(mountId);
    el.textContent = "Checking badge status";
    try {
      const res = await fetch(
        `https://api.badges.ninja/certify-badge/award/${awardId}`
      );
      if (!res.ok) {
        el.textContent = "Credential not found.";
        return;
      }
      const assertion = await res.json();
      // —— revocation check first, a resolvable assertion isn't enough on its own
      if (assertion.revoked) {
        el.textContent = `Revoked: ${assertion.revocationReason || "no reason given"}`;
        return;
      }
      el.textContent = `Verified, issued ${new Date(assertion.issuedOn).toLocaleDateString()}`;
    } catch (err) {
      el.textContent = "Verification check failed.";
    }
  }
  renderBadgeVerification("REPLACE_WITH_AWARD_ID", "badge-verify");
</script>

Nomainiet REPLACE_WITH_AWARD_ID pret īstu balvas GUID. Tā ir visa klienta puses integrācija: nav iframe robežas, ar kuru cīnīties CSS dēļ, un nav trešās puses skripta, kas līdzās verifikācijas pārbaudei ievilktu savu analītiku vai izsekošanas pikseļus.

Servera puse: Node

Ja vēlaties verificēt savā aizmugursistēmā — piemēram, pirms savā kontrolētajā profila lapā attēlojat nozīmi „Verificēts partneris” vai pirms pieņemat akreditācijas datus kā pierādījumu onboarding plūsmā — fetch ir identisks, tikai bez DOM daļas:

async function verifyAward(awardId) {
  const res = await fetch(
    `https://api.badges.ninja/certify-badge/award/${awardId}`
  );
  if (!res.ok) return { verified: false, reason: "not_found" };
  const assertion = await res.json();
  if (assertion.revoked) {
    return { verified: false, reason: assertion.revocationReason || "revoked" };
  }
  return { verified: true, issuedOn: assertion.issuedOn, badge: assertion.badge };
}

Servera puse: Python

import requests
# —— resolve the assertion, then check revocation before trusting it
def verify_award(award_id):
    res = requests.get(f"https://api.badges.ninja/certify-badge/award/{award_id}")
    if res.status_code != 200:
        return {"verified": False, "reason": "not_found"}
    assertion = res.json()
    if assertion.get("revoked"):
        return {"verified": False, "reason": assertion.get("revocationReason", "revoked")}
    return {"verified": True, "issued_on": assertion.get("issuedOn"), "badge": assertion.get("badge")}

Abi piemēri atbildi, kas nav 200, uzskata par „nav atrasts”, nevis izmet izņēmumu. Bojāts vai uzminēts balvas ID publiskam verifikācijas galapunktam ir gaidāma ievade, nevis izņēmuma situācija, tāpēc apstrādājiet to kā parastu zaru, nevis kā noķertu kļūdu.

Rezultāta stilizēšana, nevis svešas saskarnes iegulšana

Tā kā iepriekš aprakstītais logrīks ir tikai fetch izsaukums jūsu pašu DOM, katrs pikselis pieder jums. Bieži izmantots modelis ir trīs vizuāli stāvokļi, kas tieši atvasināti no atbildes:

  • Verificēts — zaļa atzīme plus „Verificēts” un izsniegšanas datums, stilizēts atbilstoši jūsu vietnes nozīmju/birku komponentiem.
  • Atsaukts — pieklusināts vai sarkans stāvoklis, kas parāda atsaukuma iemeslu, nevis to slēpj. Gan saņēmēji, gan trešās puses gūst labumu no godīga „kāpēc”, nevis klusas kļūmes.
  • Nav atrasts — vizuāli apstrādājiet to tāpat kā „atsaukts” (nerādiet viltotu veiksmes stāvokli), bet ar citu tekstu, jo nepareizs ID un apzināts atsaukums lapas lasītājam ir dažādas situācijas.

Nekas no tā neprasa komponentu bibliotēku. switch pār verified / revoked / not_found un trīs CSS klases to aptver.

Kešatmiņa, lai nenoslogotu galapunktu

Verifikācijas galapunkts ir publisks un bez autentifikācijas, kas nozīmē arī to, ka nav jāraizējas par kredītu izmaksām par pieprasījumu — taču, ja to izsauc klienta pusē bez kešošanas, tas joprojām ir tīkla apmaiņa katrā lapas ielādē. Lapai, kas katram apmeklētājam rāda vienu un to pašu nozīmi (piemēram, kājenes nozīme „Verificēts partneris”), kešojiet rezultātu serverī ar īsu TTL — pieci līdz piecpadsmit minūtes ir pilnīgi pietiekami, jo atsaukumi nav strauji mainīgs signāls — nevis ielādējiet atkārtoti katrā pieprasījumā:

const cache = new Map();
async function verifyAwardCached(awardId, ttlMs = 10 * 60 * 1000) {
  const hit = cache.get(awardId);
  if (hit && Date.now() - hit.at < ttlMs) return hit.result;
  const result = await verifyAward(awardId);
  cache.set(awardId, { result, at: Date.now() });
  return result;
}

Logrīkam katram apmeklētājam atsevišķi (saņēmējs savā personīgajā vietnē iegulst savu akreditācijas dokumentu) kešošanu izlaidiet un vienkārši izsauciet to svaigi lapas ielādē — papildu pieprasījums šādā mērogā ir niecīgs.

Ko badges.ninja saņēmējiem jau piedāvā

Pirms veidojat pilnībā pielāgotu iegulšanu, ir vērts zināt, kas jau ir pieejams uzreiz. Katras balvas publiskajā lapā ir gatavi kopīgošanas un iegulšanas fragmenti, ko saņēmēji var kopēt tieši, bez koda rakstīšanas:

Public share page with social buttons + embed snippets

Ja jūsu lietošanas gadījums ir „ļaut saņēmējam parādīt, ka viņa nozīme ir īsta”, saite uz viņa lapu badges.ninja/awards/<guid> bieži ir vienkāršāka nekā pielāgota logrīka veidošana — tā ir iepriekš parādītā cilvēkiem paredzētā lapa, un tā jau atšķir verificētu no atsaukta. Šī ieraksta pielāgoto logrīku veidojiet tad, kad verifikācijas statuss jāattēlo jūsu produkta lietotāja saskarnē — partneru katalogā, iekšējā revīzijas panelī, atlases rīkā, kas pārbauda kandidāta norādītos sertifikātus —, kur saite uz citu vietni nav pareizā lietotāja pieredze.

Kāpēc ne iframe vai piegādātāja logrīks?

Dažas platformas dod jums fragmentu, piemēram, <iframe src="https://vendor.example.com/verify-widget">, lai iegultu verifikācijas statusu. Tas darbojas, bet tam ir reālas izmaksas: jūs nevarat pārveidot saturu atbilstoši savai vietnei (esat pieķēdēti jebkuram CSS, ko piegādātājs piegādājis), tas ievieš starpizcelsmes dokumentu, ko jūsu Content-Security-Policy jāatļauj tieši, un katra lapas ielāde veic pieprasījumu trešās puses iframe resursdatoram neatkarīgi no tā, vai apmeklētāju verifikācijas statuss vispār interesē. Logrīks ar diviem fetch izsaukumiem izvairās no visiem trim — tas ir jūsu DOM, jūsu stils, un tas darbojas tikai tad, kad jūs izlemjat to izsaukt.

Visas verifikācijas ķēdes izpēte

Ja veidojat ko pamatīgāku par statusa logrīku — piemēram, revīzijas rīku, kas pārbauda akreditācijas datu partiju, vai atbilstības pārskatu —, izejiet cauri visai ķēdei, nevis apstājieties pie apgalvojuma. Apgalvojums atsaucas uz badge URL (BadgeClass: nosaukums, apraksts, kritēriji), un BadgeClass savukārt atsaucas uz issuer URL (organizācijas profils). Stingrs verificētājs atrisina visus trīs un apstiprina, ka tie ir iekšēji saskanīgi — nozīme patiešām pieder izdevējam, uz kuru tā norāda, apgalvojums patiešām atsaucas uz nozīmi, uz kuru tas norāda —, nevis tikai to, ka augšējā līmeņa apgalvojums atgriež 200. Tas ir dziļāk, nekā vajag viena akreditācijas datu statusa logrīkam, taču ir vērts zināt, ka šāda forma pastāv, ja partneris vai auditors kādreiz pajautā: „cik dziļi sniedzas jūsu verifikācija?”

Biežākās kļūdas, no kurām izvairīties

  • Tikai HTTP statusa pārbaude. Kā minēts iepriekš, atsaukts apgalvojums joprojām tiek atrisināts. Vienmēr nolasiet assertion.revoked, neizsecinot verifikāciju tikai no statusa koda.
  • Balvas ID cieta iekodēšana koplietotā komponentē. Ja logrīks paredzēts atkārtotai izmantošanai daudzu saņēmēju lapās, ņemiet balvas ID kā parametru (data atribūts, vaicājuma virkne, prop), nevis kā literāli, kas iekodēts skriptā.
  • Tīkla kļūdu kluss norīšana. try/catch, kas neko neregistrē un rāda to pašu tekstu „nav atrasts” kā patiesi trūkstošai nozīmei, vēlāk padara atkļūdošanu sāpīgu. Savos kļūdu zaros — vismaz žurnālos — nošķiriet „tīkla izsaukums neizdevās” no „API teica nē”.
  • Atkārtota verifikācija katrā renderēšanā klienta lietotnē. Ja logrīks atrodas React vai Vue komponentē, kas bieži tiek pārrenderēta, verificējiet vienreiz uz montēšanu (vai vienreiz uz kešatmiņas TTL logu, kā aprakstīts kešošanas sadaļā), nevis katrā pārrenderēšanā.

Vai tas maksā kredītus un vai tas darbojas bezmaksas plānā?

Nē. Verifikācijas galapunkts apzināti atrodas ārpus kredītu sistēmas, kas regulē izsniegšanu — nozīmes derīguma pārbaude izdevējam neko neizmaksā, un to izsaucošajam apmeklētājam nav vajadzīgs konts, API atslēga vai jebkāds plāna līmenis. Tas attiecas gan uz nozīmēm, kas izsniegtas Free, Starter vai Pro plānā: verifikācija ir paša akreditācijas dokumenta īpašība, nevis funkcija, ko ierobežo izdevēja abonements. Tāpēc šo logrīku var droši likt publiskā lapā ar neprognozējamu datplūsmu (karjeras lapā, partneru katalogā), neraizējoties par ātruma ierobežojumiem, kas saistīti ar jūsu kontu — jūs izsaucat tikai lasāmu publisku galapunktu, nevis autentificētu API maršrutu.

Vienu lietu vērts pateikt tieši: galapunkta atgrieztais apgalvojuma JSON neietver saņēmēja neapstrādātu e-pasta adresi. Saņēmēja e-pasts aizmugursistēmā tiek glabāts jaukts (hashed) tieši tāpēc, lai no publiskas verifikācijas atbildes nevarētu izgūt personīgo kontaktinformāciju — jūs saņemat pietiekami, lai apstiprinātu akreditācijas datus (nozīme, izdevējs, datumi, atsaukuma statuss), nepadarot galapunktu par potenciālo klientu ģenerēšanas rīku ikvienam, kas pārlasa balvu ID.

Gatavi izsniegt savu pirmo verificējamo akreditācijas dokumentu?

Sāciet bez maksas badges.ninja platformā — vizuālais dizainers, publiska verifikācijas lapa, PDF sertifikāts, Open Badge v2.0 izvade. Kredītkarte nav nepieciešama.

Pilnu anotēto katra apgalvojuma lauka struktūru skatiet JSON-LD lauku atsaucē. Un, ja akreditācijas datus izsniedzat programmatiski, nevis tikai verificējat, API ātrās sākšanas ceļvedis aptver autentifikāciju un balvas izveides izsaukumu, no kura rodas šī galapunkta izvade.

Nacho Coll

Par autoru

Founder & Engineer at Badges Ninja

Nacho founded Badges Ninja to make issuing verifiable digital credentials as simple as a single API call — Open Badge v2.0 badges and certificates, minted, hosted, and verifiable without standing up your own issuer infrastructure. Writes about the Open Badges spec, credential verification, and running a credentialing platform serverless on AWS, from the operator side of the wire.

Atpakaļ uz Blogu

Saistītie raksti