Laravel हर web route पर CSRF सुरक्षा लगाता है। Webhook प्रोवाइडर session cookie या CSRF token के बिना POST भेजते हैं — controller से पहले 419 मिलता है। समाधान: लक्षित CSRF छूट और $request->getContent() से raw body।
Webhook route को CSRF से छूट दें
Webhook URI को App\Http\Middleware\VerifyCsrfToken के $except में जोड़ें (Laravel 11+: bootstrap/app.php में middleware):
protected $except = [
'webhooks/stripe',
'webhooks/*',
];
केवल server-to-server path छूट दें — पूरे app का CSRF बंद न करें।
सिग्नेचर के लिए raw body पढ़ें
CSRF बायपास के बाद अछूte bytes पढ़ें:
public function handle(Request $request)
{
$payload = $request->getContent(); // raw string
$signature = $request->header('Stripe-Signature', '');
if (!$this->verifySignature($payload, $signature)) {
return response('', 401);
}
$event = json_decode($payload, true, 512, JSON_THROW_ON_ERROR);
$this->processEvent($event);
return response('', 200);
}
getContent() इस्तेमाल करें, all() या input() नहीं — Laravel helper साइन किए सटीक bytes नहीं देते।
बिज़नेस लॉजिक से पहले सिग्नेचर सत्यापित करें
हेडर निकालें, raw payload से digest बनाएँ, hash_equals से तुलना करें। असफल पर 401। सिग्नेचर सत्यापन गाइड देखें।
टनल सेट करें
- Laravel चलाएँ:
php artisan serve --port=8000। - दूसरा टर्मिनल:
npx portpreview 8000। - टनल URL + path डैशबोर्ड में पेस्ट करें।
TrustProxiesसे tunnel forwarded headers पर भरोसा करें।- टेस्ट इवेंट ट्रिगर करें।
आम जाल
बॉडी दो बार पढ़ना
json() के बाद getContent() खाली। एक बार पढ़ें, सत्यापित करें, parse करें।
Middleware क्रम
Controller से पहले global JSON parser bytes बदल देता है। Webhook route अलग रखें।
Retry और idempotency
इवेंट ID persist करें — retry और idempotency पैटर्न देखें।
और पढ़ें
मूल बातें पढ़ें localhost टनलिंग और लोकल webhook डिबगिंग. सिग्नेचर मैकेनिक्स के लिए देखें सिग्नेचर सत्यापन गाइड. डुप्लिकेट-सुरक्षित हैंडलर के लिए पढ़ें retry और idempotency पैटर्न. PortPreview मुफ़्त शुरू करें.
