दस्तावेज़प्लेटफ़ॉर्म मार्गदर्शिकाएँWebhooks

Svix लाइब्रेरी के साथ वेबहुक्स को सत्यापित करने की विधि

लाइब्रेरी का उपयोग करके सत्यापित करना

सबसे पहले, यदि आपने अभी तक नहीं किया है, तो लाइब्रेरी स्थापित करें:

npm install svix  
# Or  
yarn add svix  

फिर नीचे दिए गए कोड का उपयोग करके वेबहुक्स को सत्यापित करें। पेलोड अनुरोध का कच्चा (स्ट्रिंग) बॉडी है, और हेडर्स अनुरोध में पास किए गए हेडर्स हैं।

Use the raw request body

वेबहुक्स को सत्यापित करते समय आपको कच्चे अनुरोध बॉडी का उपयोग करना होगा, क्योंकि क्रिप्टोग्राफिक सिग्नेचर छोटे से छोटे परिवर्तन के प्रति संवेदनशील होता है। आपको उन फ्रेमवर्क्स पर ध्यान देना चाहिए जो अनुरोध को JSON के रूप में पार्स करते हैं और फिर उसे स्ट्रिंगीफाई करते हैं, क्योंकि यह भी सिग्नेचर सत्यापन को तोड़ देगा।

अलग-अलग फ्रेमवर्क्स के साथ कच्चा अनुरोध बॉडी प्राप्त करने के उदाहरण नीचे दिए गए हैं।

सिग्नेचर जो आपको एंडपॉइंट जोड़ने के स्थान से प्राप्त होना चाहिए, उदाहरण के लिए एप्लिकेशन पोर्टल।

import { Webhook } from "svix";
 
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
 
// These were all sent from the server
const headers = {
  "svix-id": "msg_p5jXN8AQM9LWM0D4loKWxJek",
  "svix-timestamp": "1614265330",
  "svix-signature": "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=",
};
const payload = '{"test": 2432232314}';
 
const wh = new Webhook(secret);
// Throws on error, returns the verified content on success
wh.verify(payload, headers); 

फ्रेमवर्क-विशिष्ट उदाहरण

यहां आपके पसंदीदा फ्रेमवर्क के अनुसार उपरोक्त उदाहरणों को कैसे समायोजित करें, इसके उदाहरण दिए गए हैं!

पायथन (डेंजो)

from django.http import HttpResponse
 
from svix.webhooks import Webhook, WebhookVerificationError
 
secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
 
@csrf_exempt
def webhook_handler(request):
    headers = request.headers
    payload = request.body
 
    try:
        wh = Webhook(secret)
        msg = wh.verify(payload, headers)
    except WebhookVerificationError as e:
        return HttpResponse(status=400)
 
    # Do something with the message...
 
    return HttpResponse(status=204)

पायथन (फ्लास्क)

from flask import request
 
from svix.webhooks import Webhook, WebhookVerificationError
 
secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
 
@app.route('/webhook/')
def webhook_handler():
    headers = request.headers
    payload = request.get_data()
 
    try:
        wh = Webhook(secret)
        msg = wh.verify(payload, headers)
    except WebhookVerificationError as e:
        return ('', 400)
 
    # Do something with the message...
 
    return ('', 204)

पायथन (फास्टAPI)

from fastapi import Request, Response, status
 
from svix.webhooks import Webhook, WebhookVerificationError
 
secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
 
@router.post("/webhook/", status_code=status.HTTP_204_NO_CONTENT)
async def webhook_handler(request: Request, response: Response):
    headers = request.headers
    payload = await request.body()
 
    try:
        wh = Webhook(secret)
        msg = wh.verify(payload, headers)
    except WebhookVerificationError as e:
        response.status_code = status.HTTP_400_BAD_REQUEST
        return
 
    # Do something with the message...

नोड.जेएस (नेक्स्ट.जेएस)

import { Webhook } from "svix";
import { buffer } from "micro";
 
export const config = {
    api: {
        bodyParser: false,
    },
}
 
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
 
export default async function handler(req, res) {
    const payload = (await buffer(req)).toString();
    const headers = req.headers;
 
    const wh = new Webhook(secret);
    let msg;
    try {
        msg = wh.verify(payload, headers);
    } catch (err) {
        res.status(400).json({});
    }
 
    // Do something with the message...
 
    res.json({});
}

नोड.जेएस (नेक्स्ट.जेएस 13 ऐप राउटर)

import { Webhook } from "svix";
 
const webhookSecret: string = process.env.WEBHOOK_SECRET || "your-secret";
 
export async function POST(req: Request) {
  const svix_id = req.headers.get("svix-id") ?? "";
  const svix_timestamp = req.headers.get("svix-timestamp") ?? "";
  const svix_signature = req.headers.get("svix-signature") ?? "";
 
  const body = await req.text();
 
  const sivx = new Webhook(webhookSecret);
 
  let msg;
  
  try {
    msg = sivx.verify(body, {
      "svix-id": svix_id,
      "svix-timestamp": svix_timestamp,
      "svix-signature": svix_signature,
    });
  } catch (err) {
    return new Response("Bad Request", { status: 400 });
  }
 
  console.log(msg);
 
  // Rest
 
  return new Response("OK", { status: 200 });
}

नोड.जेएस (नेटलिफाई फंक्शंस)

import { Webhook } from "svix";
 
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
 
 
export const handler = async ({body, headers}) => {
    const payload = body;
 
    const wh = new Webhook(secret);
    let msg;
    try {
        msg = wh.verify(payload, headers);
    } catch (err) {
        res.status(400).json({});
    }
 
    // Do something with the message...
 
    res.json({});
}

नोड.जेएस (एक्सप्रेस)

नोट: इस उदाहरण को बड़े कोडबेस में एकीकृत करते समय, आपको यह सुनिश्चित करना होगा कि express.json() मिडलवेयर को वेबहुक रूट पर लागू न करें, क्योंकि पेलोड को wh.verify के बिना किसी पूर्व पार्सिंग के बिना पास करना होगा।

import { Webhook } from "svix";
import bodyParser from "body-parser";
 
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
 
app.post('/webhook', bodyParser.raw({ type: 'application/json' }), (req, res) => {
    const payload = req.body;
    const headers = req.headers;
 
    const wh = new Webhook(secret);
    let msg;
    try {
        msg = wh.verify(payload, headers);
    } catch (err) {
        res.status(400).json({});
    }
 
    // Do something with the message...
 
    res.json({});
});

नोड.जेएस (नेस्टजेएस)

rawBody फ्लैग को सत्य पर सेट करके एप्लिकेशन को आरंभ करें। विवरण के लिए NestJS दस्तावेज़ देखें।

// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
 
async function bootstrap() {
  const app = await NestFactory.create(
    AppModule,
    { rawBody: true } // add rawBody flag
  );
  await app.listen(3000);
}
bootstrap();
// webhook.controller.ts
import { Controller, Post, RawBodyRequest, Req } from '@nestjs/common';
import { Request } from 'express';
import { Webhook } from 'svix';
 
@Controller('webhook')
class WebhookController {
  @Post()
  webhook(@Req() request: RawBodyRequest<Request>) {
    const secret = 'whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw';
    const wh = new Webhook(secret);
 
    const payload = request.rawBody.toString('utf8');
    const headers = request.headers;
 
    let msg;
    try {
      msg = wh.verify(payload, headers);
    } catch (err) {
      // handle error
    }
 
    // Do something with the message...
  }
}

Go (मानक लाइब्रेरी)

package main
 
import (
    "io"
    "log"
    "net/http"
 
    svix "github.com/svix/svix-webhooks/go"
)
 
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
 
func main() {
 
    wh, err := svix.NewWebhook(secret)
    if err != nil {
        log.Fatal(err)
    }
 
    http.HandleFunc("/webhook", func(w http.ResponseWriter, r *http.Request) {
        headers := r.Header
        payload, err := io.ReadAll(r.Body)
        if err != nil {
            w.WriteHeader(http.StatusBadRequest)
            return
        }
 
        err = wh.Verify(payload, headers)
        if err != nil {
            w.WriteHeader(http.StatusBadRequest)
            return
        }
 
        // Do something with the message...
 
        w.WriteHeader(http.StatusNoContent)
 
    })
    http.ListenAndServe(":8080", nil)
}

गो (गिन)

package main
 
import (
    "io"
    "log"
    "net/http"
 
    "github.com/gin-gonic/gin"
    svix "github.com/svix/svix-webhooks/go"
)
 
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
 
func main() {
 
    wh, err := svix.NewWebhook(secret)
    if err != nil {
        log.Fatal(err)
    }
 
    r := gin.Default()
    r.POST("/webhook", func(c *gin.Context) {
        headers := c.Request.Header
        payload, err := io.ReadAll(c.Request.Body)
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
 
        err = wh.Verify(payload, headers)
        if err != nil {
            c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
            return
        }
 
        // Do something with the message...
 
        c.JSON(200, gin.H{})
    })
    r.Run()
}

रस्ट (एक्सम)

axum राउटर में नीचे दिया गया webhook_in रूट जोड़ें।

use axum::{body::Bytes, http::StatusCode};
use hyper::HeaderMap;
 
pub const SECRET: &'static str = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
 
pub async fn webhook_in(headers: HeaderMap, body: Bytes) -> StatusCode {
    let wh = svix::webhooks::Webhook::new(SECRET);
    if let Err(_) = wh {
        return StatusCode::INTERNAL_SERVER_ERROR;
    }
 
    if let Err(_) = wh.verify(&body, &headers) {
        return StatusCode::BAD_REQUEST;
    }
 
    // Do something with the message...
 
    StatusCode::NO_CONTENT
}

रूबी (रूबी ऑन रेल्स)

एक बार जब आपने अपना प्रोजेक्ट सेट अप कर लिया है, तो config/routes.rb फ़ाइल में Rails.application.routes.draw ब्लॉक के शीर्ष पर एक रूट जोड़ें:

Rails.application.routes.draw do
  post "/webhook", to: "webhook#index"
 
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

उपरोक्त मार्ग घोषित करता है कि POST /webhook अनुरोध WebhookController की इंडेक्स एक्शन में मैप किए जाते हैं।

WebhookController और इसके इंडेक्स एक्शन को बनाने के लिए, हम नियंत्रक जनरेटर चलाएंगे ( --skip-routes विकल्प के साथ क्योंकि हमारे पास पहले से ही उपयुक्त मार्ग है):

bin/rails generate controller Webhook index --skip-routes  

रेल्स आपके लिए कई फ़ाइलें बनाएगा:

    create  app/controllers/webhook_controller.rb
    invoke  erb
    create    app/views/webhook
    create    app/views/webhook/index.html.erb
    invoke  test_unit
    create    test/controllers/webhook_controller_test.rb
    invoke  helper
    create    app/helpers/webhook_helper.rb
    invoke    test_unit
    invoke  assets
    invoke    scss
    create      app/assets/stylesheets/webhook.scss

अब हम नई बनाई गई app/controllers/webhook_controller.rb फ़ाइल में अपना सत्यापन तर्क जोड़ सकते हैं:

require  'svix'  
  
class  WebhookController  < ApplicationController  
 protect_from_forgery with:  :null_session  # disables CSRF middleware; required for API endpoints  
 def  index begin payload = request.body.read headers = request.headers wh = Svix::Webhook.new("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw")  
 json = wh.verify(payload, headers)  
 # Do something with the message...  
 head :no_content rescue head :bad_request end endend  
 

पीएचपी (लारावेल)

अपनी routes/api.php फ़ाइल में अंतिम यूज़ निर्देश के बाद निम्नलिखित जोड़ें:

use Svix\Webhook;
use Svix\Exception\WebhookVerificationException;
 
Route::post('webhook', function(Request $request) {
    $payload = $request->getContent();
    $headers = collect($request->headers->all())->transform(function ($item) {
        return $item[0];
    });
 
    try {
        $wh = new Webhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw");
        $json = $wh->verify($payload, $headers);
 
        # Do something with the message...
 
        return response()->noContent();
    } catch (WebhookVerificationException $e) {
        return response(null, 400);
    }
});