ওয়েবহুক ব্যাখ্যা: সাইনড পেলোড এবং রিট্রাই লজিক
আপনি সবেমাত্র একটি পেমেন্ট গেটওয়ে ইন্টিগ্রেট করেছেন। ডকুমেন্টেশনে বলা আছে: "পেমেন্ট সফল হলে আমরা একটি ওয়েবহুক পাঠাব।" দারুণ। কিন্তু তারপর আপনি ভাবেন: আমি কীভাবে জানব যে অনুরোধটি সত্যিই তাদের কাছ থেকে এসেছে? যদি তারা পাঠানোর সময় আমার সার্ভার ডাউন থাকে? যদি তারা একই ইভেন্ট দুবার পাঠায়?
ওয়েবহুক শক্তিশালী কিন্তু এর কিছু সমস্যা আছে। এই গাইডে আমরা ওয়েবহুকের কার্যপ্রণালী, নিরাপত্তা, এবং নির্ভরযোগ্যতার প্যাটার্ন নিয়ে আলোচনা করব যা সঠিকভাবে পরিচালনার জন্য প্রয়োজন।
ওয়েবহুক কী?
একটি ওয়েবহুক হলো একটি HTTP POST অনুরোধ যা একটি সিস্টেম অন্য সিস্টেমে পাঠায় যখন একটি নির্দিষ্ট ইভেন্ট ঘটে। আপনার অ্যাপ প্রতি কয়েক সেকেন্ডে একটি API পোল করার পরিবর্তে ("কোন নতুন অর্ডার? কোন নতুন অর্ডার?"), প্রোভাইডার কিছু ঘটলে সাথে সাথে আপনার কাছে ডেটা পুশ করে।
সাধারণ প্রবাহ:
- আপনি প্রোভাইডারের কাছে একটি URL রেজিস্টার করেন (যেমন,
https://yourapp.com/webhooks/payments)। - একটি ইভেন্ট ঘটে (পেমেন্ট সফল, ব্যবহারকারী সাইন আপ, ফাইল আপলোড)।
- প্রোভাইডার আপনার URL-এ একটি POST অনুরোধ পাঠায় যার JSON বডিতে ইভেন্টটি বর্ণনা করা থাকে।
- আপনার সার্ভার ইভেন্টটি প্রসেস করে এবং প্রাপ্তি স্বীকার করতে
2xxরেসপন্স দেয়।
যদি আপনি দ্রুত রেসপন্স না করেন (সাধারণত ৫–৩০ সেকেন্ডের মধ্যে), প্রোভাইডার ডেলিভারি ব্যর্থ বলে মনে করে এবং পুনরায় চেষ্টা করতে পারে।
কেন আপনাকে সাইনড পেলোড যাচাই করতে হবে
আপনার ওয়েবহুক এন্ডপয়েন্ট পাবলিকলি অ্যাক্সেসযোগ্য। যে কেউ URLটি খুঁজে পেলে জাল ইভেন্ট পাঠাতে পারে। যাচাই ছাড়া, একজন আক্রমণকারী "পেমেন্ট সফল" ইভেন্ট জাল করে বিনামূল্যে পণ্য পেতে পারে।
সমাধান: সাইনড পেলোড। প্রোভাইডার একটি শেয়ার্ড সিক্রেট (শুধুমাত্র আপনি এবং তারা জানেন) ব্যবহার করে অনুরোধের বডির উপর একটি ক্রিপ্টোগ্রাফিক সিগনেচার গণনা করে এবং একটি হেডারে তা অন্তর্ভুক্ত করে। আপনি আপনার প্রান্তে সিগনেচারটি পুনরায় গণনা করেন এবং তুলনা করেন।
HMAC সাইনিং কীভাবে কাজ করে
বেশিরভাগ প্রোভাইডার HMAC-SHA256 ব্যবহার করে। ধাপগুলো:
- প্রোভাইডার কাঁচা অনুরোধ বডির সাথে একটি টাইমস্ট্যাম্প সংযুক্ত করে (রিপ্লে আক্রমণ প্রতিরোধ করতে)।
- প্রোভাইডার
HMAC-SHA256(secret, timestamp + '.' + body)গণনা করে। - প্রোভাইডার একটি হেডারে সিগনেচার পাঠায়, যেমন
X-Signature: t=1234567890,v1=abc123...। - আপনি টাইমস্ট্যাম্প এবং সিগনেচার বের করেন, সিক্রেটের আপনার কপি ব্যবহার করে HMAC পুনরায় গণনা করেন, এবং একটি কনস্ট্যান্ট-টাইম তুলনা ফাংশন ব্যবহার করে তুলনা করেন।
এখানে একটি ন্যূনতম Node.js উদাহরণ:
const crypto = require('crypto');
function verifySignature(req, secret) {
const signatureHeader = req.headers['x-signature'];
const [tPart, vPart] = signatureHeader.split(',');
const timestamp = tPart.split('=')[1];
const receivedSig = vPart.split('=')[1];
const payload = timestamp + '.' + JSON.stringify(req.body);
const expectedSig = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
// টাইমিং আক্রমণ প্রতিরোধ করতে কনস্ট্যান্ট-টাইম তুলনা
return crypto.timingSafeEqual(
Buffer.from(receivedSig, 'hex'),
Buffer.from(expectedSig, 'hex')
);
}
গুরুত্বপূর্ণ: সিগনেচার যাচাইয়ের জন্য সর্বদা কাঁচা অনুরোধ বডি ব্যবহার করুন। যদি আপনার ফ্রেমওয়ার্ক JSON পার্স করে এবং পুনরায় সিরিয়ালাইজ করে, বাইট সিকোয়েন্স ভিন্ন হতে পারে, যার ফলে যাচাই ব্যর্থ হয়। পার্স করার আগে কাঁচা বডি ক্যাপচার করুন।
টাইমস্ট্যাম্প যাচাই
টাইমস্ট্যাম্পটি সাম্প্রতিক কিনা তা পরীক্ষা করুন (যেমন, ৫ মিনিটের মধ্যে)। এটি রিপ্লে আক্রমণ প্রতিরোধ করে যেখানে একজন আক্রমণকারী একটি বৈধ অনুরোধ ক্যাপচার করে পরে পুনরায় পাঠায়।
রিট্রাই লজিক: ব্যর্থতা সুন্দরভাবে পরিচালনা করা
আপনার সার্ভার ডাউন থাকতে পারে, ওভারলোডেড হতে পারে, বা নেটওয়ার্ক সমস্যা হতে পারে। প্রোভাইডাররা ব্যর্থ ডেলিভারি পুনরায় চেষ্টা করে এটি পরিচালনা করে। কিন্তু আপনাকে আপনার এন্ডপয়েন্ট ডিজাইন করতে হবে যাতে রিট্রাই নিরাপদে পরিচালনা করা যায়।
জিটার সহ এক্সপোনেনশিয়াল ব্যাকঅফ
প্রোভাইডাররা সাধারণত ক্রমবর্ধমান বিলম্বের সাথে পুনরায় চেষ্টা করে: ১ মিনিট, ৫ মিনিট, ৩০ মিনিট, ২ ঘন্টা, ইত্যাদি। এটিকে এক্সপোনেনশিয়াল ব্যাকঅফ বলা হয়। কিছু থান্ডারিং হার্ড সমস্যা এড়াতে র্যান্ডম জিটার যোগ করে।
আপনার দিক থেকে, আপনি প্রোভাইডারের রিট্রাই সময়সূচি নিয়ন্ত্রণ করেন না, তবে আপনার উচিত:
- ইভেন্টটি নিরাপদে সংরক্ষণ করার সাথে সাথে
2xxরেসপন্স দিন (এমনকি প্রসেসিং অ্যাসিঙ্ক হলেও)। - স্থায়ী ব্যর্থতার জন্য
4xxরিটার্ন করুন (যেমন, ত্রুটিপূর্ণ পেলোড) যাতে প্রোভাইডার পুনরায় চেষ্টা বন্ধ করে। - সাময়িক ব্যর্থতার জন্য
5xxরিটার্ন করুন (যেমন, ডেটাবেস ডাউন) যাতে রিট্রাই ট্রিগার হয়।
আইডেম্পোটেন্সি: নিরাপদ রিট্রাইয়ের চাবিকাঠি
রিট্রাই মানে আপনি একই ইভেন্ট একাধিকবার পেতে পারেন। আপনার প্রসেসিং আইডেম্পোটেন্ট হতে হবে—একই ইভেন্ট দুবার প্রসেস করলে একবার প্রসেস করার মতোই প্রভাব থাকবে।
সাধারণ পদ্ধতি: পেলোডে একটি অনন্য ইভেন্ট আইডি অন্তর্ভুক্ত করুন। প্রসেস করার আগে, আপনি ইতিমধ্যে সেই আইডি পরিচালনা করেছেন কিনা তা পরীক্ষা করুন। যদি হ্যাঁ, 200 রিটার্ন করুন এবং এড়িয়ে যান।
async function handleWebhook(event) {
const existing = await db.events.findOne({ id: event.id });
if (existing) {
return { status: 200, body: 'Already processed' };
}
await db.events.insert({ id: event.id, processedAt: new Date() });
await processEvent(event);
return { status: 200, body: 'OK' };
}
এই প্যাটার্নটি নিশ্চিত করে যে প্রোভাইডার ইভেন্টটি তিনবার পাঠালেও, আপনি শুধুমাত্র একবার কাজ করেন।
তুলনা: পোলিং বনাম ওয়েবহুক
| দিক | পোলিং | ওয়েবহুক |
|---|---|---|
| লেটেন্সি | ব্যবধানের উপর নির্ভর করে (যেমন, ৩০ সেকেন্ড) | প্রায় রিয়েল-টাইম |
| সার্ভার লোড | স্থির, এমনকি কোনো ইভেন্ট না থাকলেও | শুধুমাত্র ইভেন্ট ঘটলে |
| জটিলতা | বাস্তবায়ন করা সহজ | এন্ডপয়েন্ট, যাচাই, রিট্রাই প্রয়োজন |
| নির্ভরযোগ্যতা | আপনি রিট্রাই নিয়ন্ত্রণ করেন | প্রোভাইডারের রিট্রাই নীতির উপর নির্ভর করে |
রিয়েল-টাইম আপডেটের জন্য ওয়েবহুক জয়ী, তবে গুরুত্বপূর্ণ ইভেন্টের জন্য পোলিং একটি ফলব্যাক হতে পারে যদি আপনি মিসড ডেলিভারির ব্যাপারে চিন্তিত হন।
সেরা অনুশীলন চেকলিস্ট
- সর্বদা সিগনেচার যাচাই করুন। কখনো অবিশ্বস্ত ওয়েবহুক বিশ্বাস করবেন না।
- HTTPS ব্যবহার করুন। ওয়েবহুক পেলোডে প্রায়শই সংবেদনশীল ডেটা থাকে।
- দ্রুত রেসপন্স দিন। দ্রুত প্রাপ্তি স্বীকার করুন, তারপর প্রয়োজনে অ্যাসিঙ্ক্রোনাসভাবে প্রসেস করুন।
- আইডেম্পোটেন্সি বাস্তবায়ন করুন। ডুপ্লিকেট প্রসেসিং এড়াতে ইভেন্ট আইডি সংরক্ষণ করুন।
- সবকিছু লগ করুন। ডিবাগিং এবং অডিটিংয়ের জন্য প্রাপ্ত ইভেন্টের রেকর্ড রাখুন।
- ব্যর্থতা মনিটর করুন। বারবার 5xx রেসপন্স বা সিগনেচার যাচাই ব্যর্থতার জন্য অ্যালার্ট সেট আপ করুন।
- প্রকৃত পেলোড দিয়ে পরীক্ষা করুন। প্রোভাইডারের টেস্ট মোড ব্যবহার করুন বা আপনার এন্ডপয়েন্টে নমুনা ইভেন্ট পাঠান।
ওয়েবহুক সমস্যা ডিবাগ করা
ওয়েবহুক ব্যর্থ হলে, প্রথম ধাপ হলো কাঁচা অনুরোধ পরীক্ষা করা। সাধারণ সমস্যাগুলো:
- সিগনেচার মিসম্যাচ: আপনি কাঁচা বডির পরিবর্তে পার্স করা বডি ব্যবহার করছেন। কাঁচা বডি ক্যাপচার করে ঠিক করুন।
- টাইমআউট: আপনার এন্ডপয়েন্ট রেসপন্স করতে অনেক সময় নিচ্ছে। ভারী প্রসেসিং ব্যাকগ্রাউন্ড জবে সরান।
- মিসিং ইভেন্ট: ডেলিভারি লগ এবং রিট্রাই ইতিহাসের জন্য প্রোভাইডারের ড্যাশবোর্ড চেক করুন।
যদি আপনি HTTP ট্রাফিক ডিবাগ করছেন, Nginx Log Analyzer এর মতো টুল অনুরোধ ব্যর্থতা এবং রেসপন্স কোডে প্যাটার্ন খুঁজে পেতে সাহায্য করতে পারে।
সাধারণ জিজ্ঞাসা
ওয়েবহুক সিক্রেট কী এবং এটি কীভাবে সংরক্ষণ করব?
সিক্রেট হলো একটি শেয়ার্ড কী যা পেলোড সাইন করতে ব্যবহৃত হয়। এটি এনভায়রনমেন্ট ভেরিয়েবল বা সিক্রেট ম্যানেজারে সংরক্ষণ করুন—কখনো কোড বা ভার্সন কন্ট্রোলে নয়। প্রোভাইডার সমর্থন করলে পর্যায়ক্রমে এটি রোটেট করুন।
একটি প্রোভাইডার ব্যর্থ ওয়েবহুক কতবার পুনরায় চেষ্টা করবে?
এটি প্রোভাইডারভেদে ভিন্ন। কিছু ২৪ ঘন্টা এক্সপোনেনশিয়াল ব্যাকঅফ সহ পুনরায় চেষ্টা করে, অন্যরা ৩ দিন। সঠিক সময়সূচি এবং সর্বোচ্চ প্রচেষ্টার জন্য আপনার প্রোভাইডারের ডকুমেন্টেশন দেখুন।
আমি কি সার্ভারলেস ফাংশনের সাথে ওয়েবহুক ব্যবহার করতে পারি?
হ্যাঁ, কিন্তু এক্সিকিউশন টাইম লিমিট সম্পর্কে সচেতন থাকুন। ওয়েবহুক দ্রুত স্বীকার করুন (200 রিটার্ন করুন) এবং টাইমআউট এড়াতে ভারী প্রসেসিং একটি কিউ বা ব্যাকগ্রাউন্ড ফাংশনে অফলোড করুন।
শক্তিশালী ওয়েবহুক ইন্টিগ্রেশন তৈরি করতে প্রস্তুত? সিগনেচার যাচাই এবং আইডেম্পোটেন্সি বাস্তবায়ন করে শুরু করুন—এই দুটি ধাপ আপনাকে ডিবাগিংয়ের ঘন্টা বাঁচাবে এবং ব্যয়বহুল নিরাপত্তা ঘটনা প্রতিরোধ করবে।