ওয়েবহুক ব্যাখ্যা: সাইনড পেলোড ও পুনঃপ্রচেষ্টা
আপনি একটি তৃতীয় পক্ষের পরিষেবা থেকে ইভেন্ট গ্রহণ করার জন্য একটি ওয়েবহুক এন্ডপয়েন্ট তৈরি করেছেন। পরীক্ষায় সবকিছু কাজ করে, কিন্তু প্রোডাকশনে আপনি ডুপ্লিকেট ইভেন্ট, মিস হওয়া বিজ্ঞপ্তি এবং জাল অনুরোধের নিরাপত্তা উদ্বেগ লক্ষ্য করেন। সঠিক সুরক্ষা ছাড়া ওয়েবহুক বাস্তবায়নে এগুলো সাধারণ সমস্যা।
ওয়েবহুক হলো HTTP কলব্যাক যা কোনও কিছু ঘটলে পরিষেবাগুলোকে আপনার অ্যাপ্লিকেশনকে জানাতে দেয়। পোলিংয়ের বিপরীতে, এগুলো রিয়েল-টাইম আপডেট দেয়। কিন্তু নির্ভরযোগ্যভাবে ব্যবহার করতে, আপনাকে দুটি গুরুত্বপূর্ণ দিক সমাধান করতে হবে: প্রামাণিকতা (অনুরোধটি প্রত্যাশিত প্রেরকের কাছ থেকে এসেছে তা নিশ্চিত করা) এবং ডেলিভারি (ব্যর্থতা এবং পুনঃপ্রচেষ্টা পরিচালনা করা)। এই নিবন্ধটি ব্যবহারিক কোড উদাহরণসহ উভয়ই ব্যাখ্যা করে।
ওয়েবহুক কীভাবে কাজ করে
একটি ওয়েবহুক হলো একটি ব্যবহারকারী-সংজ্ঞায়িত HTTP POST এন্ডপয়েন্ট। যখন একটি ইভেন্ট ঘটে, উৎস পরিষেবা সেই URL-এ ইভেন্ট বর্ণনাকারী পেলোডসহ একটি অনুরোধ পাঠায়। উদাহরণস্বরূপ, একটি পেমেন্ট প্রসেসর চার্জ সফল হলে একটি ওয়েবহুক পাঠাতে পারে।
প্রবাহটি সহজ:
- আপনি পরিষেবার সাথে একটি ওয়েবহুক URL নিবন্ধন করেন।
- ইভেন্ট ঘটলে পরিষেবা সেই URL-এ একটি HTTP POST পাঠায়।
- আপনার এন্ডপয়েন্ট পেলোড প্রক্রিয়া করে এবং প্রাপ্তি স্বীকার করতে 2xx স্ট্যাটাস ফেরত দেয়।
সঠিক যাচাইকরণ ছাড়া, যে কেউ আপনার এন্ডপয়েন্টে অনুরোধ পাঠাতে পারে। পুনঃপ্রচেষ্টা পরিচালনা ছাড়া, ক্ষণস্থায়ী ব্যর্থতা ইভেন্ট হারাতে পারে। চলুন প্রতিটি সমাধান করি।
সাইনড পেলোড দিয়ে ওয়েবহুক সুরক্ষিত করা
একটি ওয়েবহুক প্রত্যাশিত প্রেরকের কাছ থেকে এসেছে তা নিশ্চিত করতে, পরিষেবাগুলো একটি শেয়ার্ড সিক্রেট ব্যবহার করে পেলোড সাইন করে। স্বাক্ষরটি সাধারণত অনুরোধ বডির একটি HMAC (হ্যাশ-ভিত্তিক মেসেজ অথেন্টিকেশন কোড), যা X-Signature-এর মতো একটি হেডারে পাঠানো হয়।
HMAC সাইনিং কীভাবে কাজ করে
প্রেরক একটি গোপন কী এবং কাঁচা অনুরোধ বডি ব্যবহার করে একটি HMAC গণনা করেন, তারপর হেক্স-এনকোডেড স্বাক্ষর একটি হেডারে অন্তর্ভুক্ত করেন। আপনার এন্ডপয়েন্ট একই গোপন কী দিয়ে HMAC পুনরায় গণনা করে এবং প্রাপ্ত স্বাক্ষরের সাথে তুলনা করে। যদি তারা মিলে যায়, অনুরোধটি প্রামাণিক।
Express ব্যবহার করে Node.js-এ একটি ন্যূনতম উদাহরণ:
const crypto = require('crypto');
const express = require('express');
const app = express();
// Use raw body for signature verification
app.use(express.raw({ type: 'application/json' }));
app.post('/webhook', (req, res) => {
const signature = req.headers['x-signature'];
const secret = process.env.WEBHOOK_SECRET;
const payload = req.body;
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send('Invalid signature');
}
// Process the event
const event = JSON.parse(payload);
// ... handle event
res.status(200).send('OK');
});
মূল বিষয়:
- যাচাইকরণের জন্য সর্বদা কাঁচা অনুরোধ বডি ব্যবহার করুন, পার্স করা অবজেক্ট নয়। পার্সিং পেলোড পরিবর্তন করতে পারে (যেমন, হোয়াইটস্পেস) এবং স্বাক্ষর ভাঙতে পারে।
- টাইমিং আক্রমণ প্রতিরোধ করতে টাইমিং-সেফ তুলনা ব্যবহার করুন।
- গোপন তথ্য নিরাপদে সংরক্ষণ করুন (পরিবেশ ভেরিয়েবল, সিক্রেট ম্যানেজার) এবং পর্যায়ক্রমে সেগুলো রোটেট করুন।
অতিরিক্ত নিরাপত্তা ব্যবস্থা
- টাইমস্ট্যাম্প যাচাইকরণ: স্বাক্ষরে একটি টাইমস্ট্যাম্প অন্তর্ভুক্ত করুন (যেমন,
t=timestamp,v1=signature) এবং রিপ্লে আক্রমণ প্রতিরোধ করতে কয়েক মিনিটের পুরোনো অনুরোধ প্রত্যাখ্যান করুন। - IP অ্যালাউলিস্টিং: যদি প্রদানকারী IP রেঞ্জ প্রকাশ করে, আপনার এন্ডপয়েন্ট সেই IP-তে সীমাবদ্ধ করুন।
- HTTPS: ট্রানজিটে পেলোড সুরক্ষিত রাখতে সর্বদা HTTPS ব্যবহার করুন।
নির্ভরযোগ্য পুনঃপ্রচেষ্টা বাস্তবায়ন
ওয়েবহুক ডেলিভারি নিশ্চিত নয়। নেটওয়ার্ক ব্যর্থ হয়, আপনার সার্ভার ডাউন থাকতে পারে, অথবা আপনি অ-2xx স্ট্যাটাস ফেরত দিতে পারেন। এটি পরিচালনা করতে, প্রেরকরা সাধারণত এক্সপোনেনশিয়াল ব্যাকঅফের সাথে পুনঃপ্রচেষ্টা করে। একজন প্রাপক হিসেবে, আপনাকে আপনার এন্ডপয়েন্ট ইডেম্পোটেন্ট এবং দ্রুত প্রতিক্রিয়া জানাতে ডিজাইন করতে হবে।
প্রেরকের দিকে (যদি আপনি ওয়েবহুক পাঠান)
যদি আপনি ওয়েবহুক পাঠায় এমন একটি পরিষেবা তৈরি করেন, ব্যাকঅফের সাথে পুনঃপ্রচেষ্টা বাস্তবায়ন করুন। একটি সাধারণ কৌশল:
- নেটওয়ার্ক ত্রুটি বা 5xx প্রতিক্রিয়ায় পুনঃপ্রচেষ্টা করুন।
- 4xx প্রতিক্রিয়ায় পুনঃপ্রচেষ্টা করবেন না (429 Too Many Requests ব্যতীত)।
- জিটারসহ এক্সপোনেনশিয়াল ব্যাকঅফ ব্যবহার করুন: অপেক্ষা করুন 1s, 2s, 4s, 8s, ইত্যাদি, সর্বোচ্চ পর্যন্ত।
- সর্বোচ্চ পুনঃপ্রচেষ্টার সংখ্যা নির্ধারণ করুন (যেমন, 5) এবং ব্যর্থতার জন্য ডেড-লেটার কিউ বিবেচনা করুন।
Python-এ উদাহরণ পুনঃপ্রচেষ্টা লজিক:
import time
import requests
from requests.exceptions import RequestException
def send_webhook(url, payload, max_retries=5):
for attempt in range(max_retries):
try:
response = requests.post(url, json=payload, timeout=5)
if 200 <= response.status_code < 300:
return True
elif 400 <= response.status_code < 500 and response.status_code != 429:
# Client error, don't retry
return False
except RequestException:
pass
# Exponential backoff with jitter
delay = (2 ** attempt) + random.uniform(0, 1)
time.sleep(delay)
return False
প্রাপকের দিকে
আপনার এন্ডপয়েন্টের উচিত:
- দ্রুত স্বীকার করুন: কয়েক সেকেন্ডের মধ্যে 2xx ফেরত দিন। যদি প্রক্রিয়াকরণ বেশি সময় নেয়, ইভেন্টটি কিউতে রাখুন এবং অ্যাসিঙ্ক্রোনাসভাবে প্রক্রিয়া করুন।
- ইডেম্পোটেন্ট হোন: ডুপ্লিকেট এড়াতে পেলোড থেকে একটি ইভেন্ট ID ব্যবহার করুন। প্রক্রিয়াকৃত ID সংরক্ষণ করুন এবং পুনরাবৃত্তি উপেক্ষা করুন।
- কনকারেন্সি পরিচালনা করুন: একই ইভেন্ট একসাথে প্রক্রিয়া করার সময় রেস কন্ডিশন এড়াতে ডেটাবেস ট্রানজেকশন বা লক ব্যবহার করুন।
ডেটাবেস ইউনিক কনস্ট্রেইন্ট ব্যবহার করে ইডেম্পোটেন্সি উদাহরণ:
CREATE TABLE processed_events (
event_id VARCHAR(255) PRIMARY KEY,
processed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
প্রক্রিয়াকরণের আগে, ইভেন্ট ID সন্নিবেশ করার চেষ্টা করুন। যদি এটি প্রাইমারি কী লঙ্ঘন করে, প্রক্রিয়াকরণ এড়িয়ে যান।
স্থানীয়ভাবে ওয়েবহুক পরীক্ষা করা
বিকাশের সময়, পরিষেবার আপনার স্থানীয় সার্ভারে পৌঁছানোর জন্য একটি পাবলিক URL প্রয়োজন। ngrok বা localtunnel-এর মতো টুল আপনার localhost প্রকাশ করে। সর্বদা পরীক্ষার গোপন তথ্য ব্যবহার করুন এবং বিকাশে স্বাক্ষর যাচাই করুন যাতে সমস্যাগুলো তাড়াতাড়ি ধরা পড়ে।
তুলনা: পোলিং বনাম ওয়েবহুক
| দিক | পোলিং | ওয়েবহুক |
|---|---|---|
| লেটেন্সি | ব্যবধানের উপর নির্ভর করে | প্রায় রিয়েল-টাইম |
| সার্ভার লোড | উচ্চ (ঘন ঘন অনুরোধ) | কম (শুধুমাত্র ইভেন্টে) |
| জটিলতা | বাস্তবায়ন করা সহজ | স্বাক্ষর যাচাইকরণ এবং পুনঃপ্রচেষ্টা পরিচালনা প্রয়োজন |
| নির্ভরযোগ্যতা | আপনি পুনঃপ্রচেষ্টা নিয়ন্ত্রণ করেন | প্রেরকের পুনঃপ্রচেষ্টা নীতির উপর নির্ভর করে |
সাধারণ প্রশ্ন
সাইনড ওয়েবহুক পেলোড কী?
একটি সাইনড পেলোডে একটি শেয়ার্ড সিক্রেট দিয়ে তৈরি একটি ক্রিপ্টোগ্রাফিক স্বাক্ষর (সাধারণত HMAC) থাকে। এটি প্রাপককে যাচাই করতে দেয় যে অনুরোধটি প্রত্যাশিত প্রেরকের কাছ থেকে এসেছে এবং টেম্পার করা হয়নি।
আমি কীভাবে ডুপ্লিকেট ওয়েবহুক ডেলিভারি পরিচালনা করব?
পেলোড থেকে একটি অনন্য ইভেন্ট ID ব্যবহার করে আপনার এন্ডপয়েন্ট ইডেম্পোটেন্ট করুন। প্রক্রিয়াকৃত ID সংরক্ষণ করুন এবং ডুপ্লিকেট উপেক্ষা করুন। এটি নিশ্চিত করে যে পুনঃপ্রচেষ্টা বা নেটওয়ার্ক সমস্যা দ্বিগুণ প্রক্রিয়াকরণ ঘটায় না।
আমার কি ব্যর্থ ওয়েবহুক ডেলিভারি পুনঃপ্রচেষ্টা করা উচিত?
হ্যাঁ, কিন্তু শুধুমাত্র ক্ষণস্থায়ী ত্রুটির জন্য (নেটওয়ার্ক সমস্যা, 5xx)। জিটারসহ এক্সপোনেনশিয়াল ব্যাকঅফ ব্যবহার করুন এবং সর্বোচ্চ পুনঃপ্রচেষ্টা সীমা নির্ধারণ করুন। 4xx ত্রুটিতে পুনঃপ্রচেষ্টা এড়িয়ে চলুন (429 ব্যতীত) কারণ তারা অনুরোধের নিজেই একটি সমস্যা নির্দেশ করে।
ওয়েবহুক পেলোড ডিবাগ করার সময়, আপনাকে প্রায়ই JSON ডেটা পরিদর্শন করতে হয়। JSON Formatter আপনাকে দ্রুত JSON পেলোড সুন্দরভাবে প্রিন্ট এবং যাচাই করতে সাহায্য করতে পারে।