Skip to content
Makala zote

Kuthibitisha sahihi za webhook na kushughulikia majaribio tena kwa usahihi

Charles Archibong

, Mwanzilishi mwenza

Thibitisha sahihi ya V2 juu ya baiti mbichi za ombi, kataa mihuri ya muda nje ya dirisha la marudio, rekodi Kitambulisho cha tukio chini ya kizuizi cha kipekee kabla ya kufanya kazi yoyote, na urudishe 2xx mara tu tukio litakapohifadhiwa kwa muda mrefu.

Kichwa cha habari "Saini na majaribio ya wavuti" kando ya kielelezo cha dirisha la msimbo lenye mabano ya pembe, kwenye gradient ya kina ya indigo.

Mambo muhimu

  • Hesabu HMAC juu ya baiti ghafi za ombi, kamwe usitumie JSON iliyosasishwa tena kupita kiasi.
  • Muhuri wa muda uliosainiwa pamoja na dirisha la marudio ndio unaozuia uwasilishaji wa zamani, uliosainiwa halali kurudiwa.
  • Kutoa nakala kwenye Kitambulisho cha tukio, si Kitambulisho cha uwasilishaji: kutuma upya kwa mikono ni uwasilishaji mpya wa tukio lile lile.
  • Rudisha 2xx tu baada ya tukio kuhifadhiwa kwa muda mrefu, na ufanye kazi polepole baadaye.

Kipokeaji cha wavuti kina kazi tatu, na hutokea kwa mpangilio maalum. Thibitisha ombi hilo lilitoka Toden kwa kuangalia sahihi juu ya baiti halisi zilizopokelewa. Thibitisha kuwa ni mpya kwa kuangalia muhuri wa muda uliosainiwa dhidi ya dirisha la marudio. Kisha thibitisha kuwa hujachukua hatua tayari kwa kurekodi Kitambulisho cha tukio chini ya kizuizi cha kipekee. Ni baada ya hizo tatu tu ndipo unarudi.2xx, na baada ya hapo tu ndipo unafanya kazi halisi.

Ukikosea agizo na kila hitilafu itakuwa kimya. Chunguza kabla ya kuthibitisha na mwili ulioghushiwa utafikia mantiki ya biashara yako. Ruka muhuri wa muda na ombi lililonaswa linaweza kurudiwa tena kwa muda usiojulikana. Rudisha kwenye kitufe kisicho sahihi na utume tena mteja mara mbili. Makala haya yanapitia kila hatua kwa Toden webhooks (hufunguka kwenye kichupo kipya) , ukiwa na kipokezi unaweza kuzoea.

Kinachofika na kila uwasilishaji

Kila uwasilishaji ni HTTP POSTna JSON mwili na seti ya vichwa vya habari. Vile ambavyo ni muhimu kwa uthibitisho, kama ilivyoandikwa chini ya uthibitishaji wa webhook (hufunguka kwenye kichupo kipya) :

Kichwa

Mfano

Nini cha kufanya nayo

X-Myaza-Signature-V2

t=1786441200,v1=8df1…

Changanua muhuri wa muda na kilav1thamani. Thibitisha dhidi ya hizi.

X-Myaza-Replay-Window

300

Dirisha la marudio la sehemu ya mwisho kwa sekunde. Halijasainiwa, kwa hivyo usiruhusu lipanue hundi yako.

X-Myaza-Event-Id

evt_…

Ufunguo thabiti wa kutoa nakala.

X-Myaza-Delivery

del_…

Rekodi ya uwasilishaji. Inafaa kwa ufuatiliaji, si kwa ajili ya uwasilishaji.

X-Myaza-Event

verification.completed

Kwa ajili ya uelekezaji. Mwili uliosainiwa unabaki kuwa na mamlaka.

X-Myaza-Signature

sha256=…

Saini ya utangamano wa zamani juu ya mwili pekee.

Kama umejenga dhidi ya mzeeX-Myaza-SignatureKichwa cha habari, bado kinafanya kazi. Kinaashiria mwili bila muhuri wa muda, kumaanisha kuwa hakiwezi kukuambia kama ombi ni jipya. Nenda kwenye kichwa cha habari cha V2.

Hatua ya 1: thibitisha sahihi juu ya baiti mbichi

Saini ni heksaidi ndogo HMAC - SHA256 , iliyo na siri yako ya mwisho, juu ya kamba<t>.<rawBody>: muhuri wa muda kutoka kwa kichwa cha habari, sehemu kamili, kisha mwili wa ombi jinsi ulivyofika.

"Kama ilivyofika" ndiyo sehemu inayovunja miunganisho. Mifumo mingi ya wavuti huchanganua JSON kabla ya kidhibiti chako kuanza. Ukithibitisha dhidi yaJSON.stringify(req.body), unasaini urekebishaji upya wa serial: nafasi nyeupe, mpangilio wa vitufe na umbizo la nambari vyote vinaweza kutofautiana na kile kilichosainiwa, na uthibitishaji hushindwa mara kwa mara kwa njia zinazoonekana kama siri mbaya. Sanidi njia ili ikupe bafa ghafi.

Linganisha kwa kutumia kitendakazi cha wakati usiobadilika, na ulinganishe dhidi ya kilav1thamani, si ya kwanza tu. Wakati wa mzunguko wa siri Toden husaini siri inayotumika na ile iliyoondolewa, kwa hivyo kichwa cha habari hubeba wagombea wawili. Kubali ombi ikiwa yoyote kati yao inalingana, na uondoe siri ya zamani tu baada ya muda wake wa ziada kuisha kwenye dashibodi.

Hatua ya 2: kataa mihuri ya muda iliyopitwa na wakati

Saini halali inathibitisha ni nani aliyetuma ombi, si lini. Mtu yeyote aliyenasa uwasilishaji (kutoka kwa kumbukumbu ya proksi, tuseme) anaweza kuutuma tena, na bado ungethibitisha. Muhuri wa muda uliosainiwa unafunga pengo hilo: kwa sababutiko ndani ya mfuatano uliosainiwa, mshambuliaji hawezi kuubadilisha bila kuvunja sahihi.

Kataa uwasilishaji wowote ambao muhuri wake wa muda haupo, hauwezi kusomwa, ni wa zamani kuliko dirisha la marudio, au ni mbali sana katika siku zijazo.X-Myaza-Replay-Windowinakuambia dirisha lililosanidiwa la sehemu ya mwisho, lakini kichwa hicho cha habari kiko nje ya kamba iliyosainiwa, kwa hivyo mtu yeyote anayerudia ombi anaweza kulibadilisha. Kitumie kukaza hundi yako ukipenda, usiipanue kamwe: kiweke kwenye dirisha ulilosanidi kwa sehemu ya mwisho. Hakikisha saa ya seva yako imesawazishwa; saa inayosogea hubadilisha hundi hii kuwa kukataliwa bila mpangilio.

Kurudi401kwa sahihi iliyopotea, iliyopitwa na wakati au batili. Usirudishe200ili kufanya majaribio ya kurudia yasimame: hiyo inamwambia mtumaji kwamba tukio limekubaliwa.

Hatua ya 3: toa ofa kwenye tukio, sio uwasilishaji

Vizuizi vya wavuti huwasilishwa angalau mara moja. Kipokeaji kinachokatiza, mlio wa mtandao baada ya wewe kujibu, au mwenzako anayebonyeza Tuma Upya kwenye dashibodi vyote vitaweka tukio lile lile mbele yako tena.

Swali ni kitambulisho kipi kinamaanisha "kitu kile kile". Kuna wagombea wawili, na wana tabia tofauti:

  • Kitambulisho cha tukio (X-Myaza-Event-Idnaidkatika bahasha) hutambua tukio la biashara. Linabaki vile vile katika majaribio ya kiotomatiki na katika kutuma tena kwa mikono.

  • Kitambulisho cha uwasilishaji (X-Myaza-Delivery) hutambua rekodi moja ya uwasilishaji. Kutuma upya kwa mikono huunda rekodi nyingine ya uwasilishaji, kwa hivyo hupata kitambulisho kipya cha uwasilishaji.

Weka uwasilishaji wako kwenye Kitambulisho cha tukio. Mwongozo wa upimaji wa webhook (hufunguka kwenye kichupo kipya) unasema hivi moja kwa moja na unapendekeza kiambatisho ambacho hakifanyi chochote kwenye mzozo:

insert into received_myaza_events (event_id, event_type, payload)
values (:id, :type, :payload)
on conflict (event_id) do nothing;

Tukio moja linahitaji uangalifu.verification.status_updatedimetumwa tambarare, haijafungwa ndani ya{ id, event, createdAt, data }bahasha matumizi ya matukio mengine, kwa hivyo mwili haunaidSehemu. Kuchukua kitambulisho cha tukio kutoka kwa kichwa cha habari hufanya kazi kwa kila aina ya tukio, ambayo ndiyo sheria rahisi zaidi.

Hatua ya 4: kubali haraka, kisha fanya kazi

Kurudi2xxMara tu tukio litakapohifadhiwa kwa muda mrefu, na si kabla. Kisha lishughulikie nje ya ombi: sasisha rekodi ya mteja, mjulishe mwombaji, fungua tiketi ya ndani. Usindikaji wa polepole ndani ya ombi hualika muda wa kuisha, na muda wa kuisha huchukuliwa kama hitilafu na kujaribu tena.

Aina za matukio yasiyojulikana zinapaswa kuhifadhiwa au kupuuzwa na bado zikubaliwe. Matukio mapya huongezwa kwenye orodha baada ya muda; kukataa moja usilolitambua hutoa mzunguko wa kujaribu tena kwa kitu ambacho hukukusudia kukishughulikia.

Mpokeaji anayefanya yote manne

Imechukuliwa kutoka kwa mfano wa Node.js katika nyaraka, huku dirisha la marudio likiwa limefunikwa na kiingilio cha kurudisha nyuma kikiwa kimeongezwa.saveEventOncenaqueuesimama kwa ajili ya hifadhi yako mwenyewe na mkimbiaji wa kazi.

import crypto from "node:crypto";
import express from "express";

const app = express();

app.post("/webhooks/myaza", express.raw({ type: "application/json" }), async (req, res) => {
  const parts = String(req.header("X-Myaza-Signature-V2") || "").split(",");
  const timestamp = parts.find((p) => p.startsWith("t="))?.slice(2);
  const candidates = parts.filter((p) => p.startsWith("v1=")).map((p) => p.slice(3));
  const MAX_WINDOW = 300; // the replay window configured for this endpoint
  const windowSeconds = Math.min(Number(req.header("X-Myaza-Replay-Window")) || MAX_WINDOW, MAX_WINDOW);

  if (!timestamp || Math.abs(Date.now() / 1000 - Number(timestamp)) > windowSeconds) {
    return res.status(401).send("Expired signature");
  }

  const expected = crypto
    .createHmac("sha256", process.env.MYAZA_WEBHOOK_SECRET)
    .update(`${timestamp}.`)
    .update(req.body)
    .digest("hex");

  const valid = candidates.some((c) =>
    c.length === expected.length &&
    crypto.timingSafeEqual(Buffer.from(c), Buffer.from(expected))
  );
  if (!valid) return res.status(401).send("Invalid signature");

  const eventId = req.header("X-Myaza-Event-Id");
  const payload = JSON.parse(req.body.toString("utf8"));
  const isNew = await saveEventOnce(eventId, req.header("X-Myaza-Event"), payload);

  res.status(200).send("OK");
  if (isNew) queue.add("myaza-event", { eventId });
});

Kwa sababu tukio huhifadhiwa kabla ya jibu, mgongano kati ya jibu naqueue.addHapotezi chochote: kuwa na mfagiaji mdogo akichukua matukio yaliyohifadhiwa ambayo hayakushughulikiwa kamwe. Wakati wa mzunguko, weka siri zote mbili na ukokote thamani inayotarajiwa kwa kila moja; hundi kisha hupita ikiwa mgombea yeyote analingana na siri yoyote.

Jinsi majaribio yanavyoendelea, na yanamaanisha nini kwako

Uwasilishaji ambao haupokei2xx, au times out, hujaribiwa tena kwa backoff:

Jaribio

Kuchelewa baada ya jaribio la awali

1

Sekunde 30

2

Dakika 5

3

Dakika 30

4

Saa 2

5

Saa 24

Baada ya majaribio matano yaliyoshindwa, uwasilishaji unaonyeshwaFAILEDna inaweza kujaribiwa tena kwa mikono kutoka kwenye dashibodi. Matokeo mawili yanafuata.

Kwanza, hitilafu upande wako ya siku moja au mbili inaweza kurejeshwa bila kupoteza data, mradi tu uirekebishe kabla ya jaribio la mwisho na ushughulikie majaribio mengi bila kujali unaporudi. Tahadhari kuhusu hitilafu za uwasilishaji zinazojirudia ili ujifunze kuhusu hitilafu hiyo kutoka kwa ufuatiliaji wako badala ya kutoka kwa mteja.

Pili, uwasilishaji hujaribu tena kwa kujitegemea, ili uweze kufika nje ya mpangilio. Tuseme mtiririko wako wa kazi unaelekeza uthibitishaji ili upitiwe na afisa wa uzingatiaji sheria anaidhinisha saa moja baadaye: mbiliverification.status_updatedmatukio, kila moja ikiwa na ratiba yake ya kujaribu tena. Ikiwa uwasilishaji wa kwanza ulishindwa na ukafanikiwa wakati wa kujaribu tena, unaweza kupokeaapprovedkablain_reviewSheria iliyoandikwa ni kushughulikia mambo ya hivi karibunichangedAtkama mkondo wa sasa, kwa hivyo ihifadhi na upuuze sasisho la zamani kuliko ulilo nalo. Pale ambapo hatari ni kubwa, soma hali ya mkondo kutoka API kabla ya kutenda.

Ijaribu kabla ya uzalishaji

Unda sehemu ya mwisho ya kisanduku cha mchanga na utumie kiigaji kwenye ukurasa wa sehemu ya mwisho kutuma matukio ya sampuli yaliyosainiwa kwa usahihi kupitia njia halisi ya uwasilishaji. Kisha shughulikia kesi za hitilafu kwa makusudi:

  1. Tuma tukio lililoigwa na uthibitishe kuwa mpokeaji anathibitisha sahihi ya V2 na anarudisha2xxharaka.

  2. Badilisha baiti moja ya mwili uliokamatwa na uthibitishe401.

  3. Cheza tena ombi lililonaswa baada ya dirisha kupita na uthibitishe401.

  4. Tuma tena uwasilishaji kutoka kwenye dashibodi na uthibitishe athari yako ya upande hutokea mara moja.

  5. Rudisha isiyo ya2xxkwa muda na kuthibitisha kuwa jaribio jipya limepangwa.

  6. Zungusha siri na uthibitishe kwamba sahihi zote mbili zinakubaliwa wakati wa kipindi cha neema.

Mpokeaji anayepitisha zote sita atafanya ipasavyo siku ambayo kitu kitaenda vibaya, ambayo ndiyo siku pekee muhimu.

Vyanzo

Charles Archibong

Kuhusu mwandishi

Charles Archibong

Mwanzilishi mwenza

Charles Archibong ndiye mwanzilishi mwenza wa Toden. Anaandika kuhusu uthibitishaji wa utambulisho, teknolojia ya kifedha, na kazi ya vitendo ya kujenga huduma za kidijitali zinazoaminika.

Jenga bidhaa yako.Tutashughulikia yaliyobaki.

Utambulisho na uzingatiaji tangu mwanzo hadi mwisho, kwa viwango vya kimataifa na bei zinazowafaa waanzilishi.