Tutorial: Membuat titik akhir webhook menggunakan URL fungsi Lambda - AWS Lambda

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Tutorial: Membuat titik akhir webhook menggunakan URL fungsi Lambda

Dalam tutorial ini, Anda membuat URL fungsi Lambda untuk mengimplementasikan endpoint webhook. Webhook adalah komunikasi ringan yang digerakkan oleh peristiwa yang secara otomatis mengirimkan data antar aplikasi menggunakan HTTP. Anda dapat menggunakan webhook untuk menerima pembaruan langsung tentang peristiwa yang terjadi di sistem lain, seperti ketika pelanggan baru mendaftar di situs web, pembayaran diproses, atau file diunggah.

Dengan Lambda, webhook dapat diimplementasikan menggunakan fungsi Lambda atau API Gateway. URLs Fungsi URLs adalah pilihan yang baik untuk webhook sederhana yang tidak memerlukan fitur seperti otorisasi lanjutan atau validasi permintaan.

Tip

Jika Anda tidak yakin solusi mana yang terbaik untuk kasus penggunaan khusus Anda, lihatPilih metode untuk menjalankan fungsi Lambda Anda menggunakan permintaan HTTP.

Prasyarat

Untuk menyelesaikan tutorial ini, Anda harus memiliki Python (versi 3.8 atau yang lebih baru) atau Node.js (versi 18 atau lebih baru) diinstal pada mesin lokal Anda.

Untuk menguji titik akhir menggunakan permintaan HTTP, tutorial menggunakan curl, alat baris perintah yang dapat Anda gunakan untuk mentransfer data menggunakan berbagai protokol jaringan. Lihat dokumentasi curl untuk mempelajari cara menginstal alat jika Anda belum memilikinya.

Buat fungsi Lambda

Pertama buat fungsi Lambda yang berjalan ketika permintaan HTTP dikirim ke titik akhir webhook Anda. Dalam contoh ini, aplikasi pengiriman mengirimkan pembaruan setiap kali pembayaran dikirimkan dan menunjukkan di badan permintaan HTTP apakah pembayaran berhasil. Fungsi Lambda mem-parsing permintaan dan mengambil tindakan sesuai dengan status pembayaran. Dalam contoh ini, kode hanya mencetak ID pesanan untuk pembayaran, tetapi dalam aplikasi nyata, Anda dapat menambahkan pesanan ke database atau mengirim pemberitahuan.

Fungsi ini juga mengimplementasikan metode otentikasi yang paling umum digunakan untuk webhook, otentikasi pesan berbasis hash (HMAC). Dengan metode ini, aplikasi pengirim dan penerima berbagi kunci rahasia. Aplikasi pengiriman menggunakan algoritma hashing untuk menghasilkan tanda tangan unik menggunakan kunci ini bersama dengan konten pesan, dan menyertakan tanda tangan dalam permintaan webhook sebagai header HTTP. Aplikasi penerima kemudian mengulangi langkah ini, menghasilkan tanda tangan menggunakan kunci rahasia, dan membandingkan nilai yang dihasilkan dengan tanda tangan yang dikirim di header permintaan. Jika hasilnya cocok, permintaan dianggap sah.

Buat fungsi menggunakan konsol Lambda dengan runtime Python atau Node.js.

Python
Buat fungsi Lambda
  1. Buka halaman Fungsi di konsol Lambda.

  2. Buat fungsi dasar 'Hello world' dengan melakukan hal berikut:

    1. Pilih Buat fungsi.

    2. Pilih Penulis dari awal.

    3. Untuk Nama fungsi, masukkan myLambdaWebhook.

    4. Untuk Runtime, pilih python3.13.

    5. Pilih Buat fungsi.

  3. Di panel Sumber kode, ganti kode yang ada dengan menyalin dan menempelkan berikut ini:

    import json import hmac import hashlib import os def lambda_handler(event, context): # Get the webhook secret from environment variables webhook_secret = os.environ['WEBHOOK_SECRET'] # Verify the webhook signature if not verify_signature(event, webhook_secret): return { 'statusCode': 401, 'body': json.dumps({'error': 'Invalid signature'}) } try: # Parse the webhook payload payload = json.loads(event['body']) # Handle different event types event_type = payload.get('type') if event_type == 'payment.success': # Handle successful payment order_id = payload.get('orderId') print(f"Processing successful payment for order {order_id}") # Add your business logic here # For example, update database, send notifications, etc. elif event_type == 'payment.failed': # Handle failed payment order_id = payload.get('orderId') print(f"Processing failed payment for order {order_id}") # Add your business logic here else: print(f"Received unhandled event type: {event_type}") # Return success response return { 'statusCode': 200, 'body': json.dumps({'received': True}) } except json.JSONDecodeError: return { 'statusCode': 400, 'body': json.dumps({'error': 'Invalid JSON payload'}) } except Exception as e: print(f"Error processing webhook: {e}") return { 'statusCode': 500, 'body': json.dumps({'error': 'Internal server error'}) } def verify_signature(event, webhook_secret): """ Verify the webhook signature using HMAC """ try: # Get the signature from headers signature = event['headers'].get('x-webhook-signature') if not signature: print("Error: Missing webhook signature in headers") return False # Get the raw body (return an empty string if the body key doesn't exist) body = event.get('body', '') # Create HMAC using the secret key expected_signature = hmac.new( webhook_secret.encode('utf-8'), body.encode('utf-8'), hashlib.sha256 ).hexdigest() # Compare the expected signature with the received signature to authenticate the message is_valid = hmac.compare_digest(signature, expected_signature) if not is_valid: print(f"Error: Invalid signature. Received: {signature}, Expected: {expected_signature}") return False return True except Exception as e: print(f"Error verifying signature: {e}") return False
  4. Di bagian DEPLOY, pilih Deploy untuk memperbarui kode fungsi Anda.

Node.js
Buat fungsi Lambda
  1. Buka halaman Fungsi di konsol Lambda.

  2. Buat fungsi dasar 'Hello world' dengan melakukan hal berikut:

    1. Pilih Buat fungsi.

    2. Pilih Penulis dari awal.

    3. Untuk Nama fungsi, masukkan myLambdaWebhook.

    4. Untuk Runtime, pilih nodejs22.x.

    5. Pilih Buat fungsi.

  3. Di panel Sumber kode, ganti kode yang ada dengan menyalin dan menempelkan berikut ini:

    import crypto from 'crypto'; export const handler = async (event, context) => { // Get the webhook secret from environment variables const webhookSecret = process.env.WEBHOOK_SECRET; // Verify the webhook signature if (!verifySignature(event, webhookSecret)) { return { statusCode: 401, body: JSON.stringify({ error: 'Invalid signature' }) }; } try { // Parse the webhook payload const payload = JSON.parse(event.body); // Handle different event types const eventType = payload.type; switch (eventType) { case 'payment.success': { // Handle successful payment const orderId = payload.orderId; console.log(`Processing successful payment for order ${orderId}`); // Add your business logic here // For example, update database, send notifications, etc. break; } case 'payment.failed': { // Handle failed payment const orderId = payload.orderId; console.log(`Processing failed payment for order ${orderId}`); // Add your business logic here break; } default: console.log(`Received unhandled event type: ${eventType}`); } // Return success response return { statusCode: 200, body: JSON.stringify({ received: true }) }; } catch (error) { if (error instanceof SyntaxError) { // Handle JSON parsing errors return { statusCode: 400, body: JSON.stringify({ error: 'Invalid JSON payload' }) }; } // Handle all other errors console.error('Error processing webhook:', error); return { statusCode: 500, body: JSON.stringify({ error: 'Internal server error' }) }; } }; // Verify the webhook signature using HMAC const verifySignature = (event, webhookSecret) => { try { // Get the signature from headers const signature = event.headers['x-webhook-signature']; if (!signature) { console.log('No signature found in headers:', event.headers); return false; } // Get the raw body (return an empty string if the body key doesn't exist) const body = event.body || ''; // Create HMAC using the secret key const hmac = crypto.createHmac('sha256', webhookSecret); const expectedSignature = hmac.update(body).digest('hex'); // Compare expected and received signatures const isValid = signature === expectedSignature; if (!isValid) { console.log(`Invalid signature. Received: ${signature}, Expected: ${expectedSignature}`); return false; } return true; } catch (error) { console.error('Error during signature verification:', error); return false; } };
  4. Di bagian DEPLOY, pilih Deploy untuk memperbarui kode fungsi Anda.

Buat kunci rahasia

Untuk fungsi Lambda untuk mengotentikasi permintaan webhook, ia menggunakan kunci rahasia yang dibagikan dengan aplikasi panggilan. Dalam contoh ini, kunci disimpan dalam variabel lingkungan. Dalam aplikasi produksi, kami sarankan Anda menggunakannya AWS Secrets Manager sebagai opsi yang lebih aman. Untuk mempelajari selengkapnya tentang menggunakan Secrets Manager untuk menyimpan kunci rahasia, lihat Membuat AWS Secrets Manager rahasia dan Mendapatkan rahasia dari AWS Secrets Manager Panduan AWS Secrets Manager Pengguna.

Buat dan simpan kunci rahasia webhook
  1. Hasilkan string acak yang panjang menggunakan generator nomor acak yang aman secara kriptografis. Anda dapat menggunakan cuplikan kode berikut dengan Python atau Node.js untuk menghasilkan dan mencetak rahasia 32 karakter, atau menggunakan metode pilihan Anda sendiri.

    Python
    contoh kode untuk menghasilkan rahasia
    import secrets webhook_secret = secrets.token_urlsafe(32) print(webhook_secret)
    Node.js
    contoh kode untuk menghasilkan rahasia (format modul ES)
    import crypto from 'crypto'; let webhookSecret = crypto.randomBytes(32).toString('base64'); console.log(webhookSecret)
  2. Simpan string yang Anda hasilkan sebagai variabel lingkungan untuk fungsi Anda dengan melakukan hal berikut:

    1. Di tab Konfigurasi untuk fungsi Anda, pilih variabel Lingkungan.

    2. Pilih Edit.

    3. Pilih Tambahkan variabel lingkungan.

    4. Untuk Kunci, masukkanWEBHOOK_SECRET, lalu untuk Nilai, masukkan rahasia yang Anda buat di langkah sebelumnya.

    5. Pilih Simpan.

Anda harus menggunakan rahasia ini lagi nanti di tutorial untuk menguji fungsi Anda, jadi catat sekarang.

Buat titik akhir URL fungsi

Buat titik akhir untuk webhook Anda menggunakan URL fungsi Lambda. Karena Anda menggunakan jenis autentikasi NONE untuk membuat titik akhir dengan akses publik, siapa pun yang memiliki URL dapat memanggil fungsi Anda. Untuk mempelajari lebih lanjut tentang mengontrol akses ke fungsi URLs, lihatKontrol akses ke fungsi Lambda URLs. Jika Anda memerlukan opsi otentikasi lanjutan untuk webhook Anda, pertimbangkan untuk menggunakan API Gateway.

Buat titik akhir URL fungsi
  1. Di tab Konfigurasi untuk fungsi Anda, pilih URL Fungsi.

  2. Pilih Buat URL fungsi.

  3. Untuk jenis Auth, pilih NONE.

  4. Pilih Simpan.

Titik akhir untuk URL fungsi yang baru saja Anda buat ditampilkan di panel URL Fungsi. Salin titik akhir untuk digunakan nanti dalam tutorial.

Uji fungsi di konsol

Sebelum menggunakan permintaan HTTP untuk menjalankan fungsi Anda menggunakan titik akhir URL, uji di konsol untuk mengonfirmasi kode Anda berfungsi seperti yang diharapkan.

Untuk memverifikasi fungsi di konsol, pertama-tama Anda menghitung tanda tangan webhook menggunakan rahasia yang Anda buat sebelumnya dalam tutorial dengan payload JSON pengujian berikut:

{ "type": "payment.success", "orderId": "1234", "amount": "99.99" }

Gunakan salah satu contoh kode Python atau Node.js berikut untuk menghitung tanda tangan webhook menggunakan rahasia Anda sendiri.

Python
Hitung tanda tangan webhook
  1. Simpan kode berikut sebagai file bernamacalculate_signature.py. Ganti rahasia webhook dalam kode dengan nilai Anda sendiri.

    import secrets import hmac import json import hashlib webhook_secret = "arlbSDCP86n_1H90s0fL_Qb2NAHBIBQOyGI0X4Zay4M" body = json.dumps({"type": "payment.success", "orderId": "1234", "amount": "99.99"}) signature = hmac.new( webhook_secret.encode('utf-8'), body.encode('utf-8'), hashlib.sha256 ).hexdigest() print(signature)
  2. Hitung tanda tangan dengan menjalankan perintah berikut dari direktori yang sama tempat Anda menyimpan kode. Salin tanda tangan output kode.

    python calculate_signature.py
Node.js
Hitung tanda tangan webhook
  1. Simpan kode berikut sebagai file bernamacalculate_signature.mjs. Ganti rahasia webhook dalam kode dengan nilai Anda sendiri.

    import crypto from 'crypto'; const webhookSecret = "arlbSDCP86n_1H90s0fL_Qb2NAHBIBQOyGI0X4Zay4M" const body = "{\"type\": \"payment.success\", \"orderId\": \"1234\", \"amount\": \"99.99\"}"; let hmac = crypto.createHmac('sha256', webhookSecret); let signature = hmac.update(body).digest('hex'); console.log(signature);
  2. Hitung tanda tangan dengan menjalankan perintah berikut dari direktori yang sama tempat Anda menyimpan kode. Salin tanda tangan output kode.

    node calculate_signature.mjs

Anda sekarang dapat menguji kode fungsi Anda menggunakan permintaan HTTP pengujian di konsol.

Uji fungsi di konsol
  1. Pilih tab Kode untuk fungsi Anda.

  2. Di bagian TEST EVENTS, pilih Create new test event

  3. Untuk Nama Acara, masukkanmyEvent.

  4. Ganti JSON yang ada dengan menyalin dan menempelkan berikut ini ke panel Event JSON. Ganti tanda tangan webhook dengan nilai yang Anda hitung pada langkah sebelumnya.

    { "headers": { "Content-Type": "application/json", "x-webhook-signature": "2d672e7a0423fab740fbc040e801d1241f2df32d2ffd8989617a599486553e2a" }, "body": "{\"type\": \"payment.success\", \"orderId\": \"1234\", \"amount\": \"99.99\"}" }
  5. Pilih Simpan.

  6. Pilih Panggil.

    Anda akan melihat output yang serupa dengan yang berikut:

    Python
    Status: Succeeded Test Event Name: myEvent Response: { "statusCode": 200, "body": "{\"received\": true}" } Function Logs: START RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6 Version: $LATEST Processing successful payment for order 1234 END RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6 REPORT RequestId: 50cc0788-d70e-453a-9a22-ceaa210e8ac6 Duration: 1.55 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 36 MB Init Duration: 136.32 ms
    Node.js
    Status: Succeeded Test Event Name: myEvent Response: { "statusCode": 200, "body": "{\"received\":true}" } Function Logs: START RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 Version: $LATEST 2025-01-10T18:05:42.062Z e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 INFO Processing successful payment for order 1234 END RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 REPORT RequestId: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 Duration: 60.10 ms Billed Duration: 61 ms Memory Size: 128 MB Max Memory Used: 72 MB Init Duration: 174.46 ms Request ID: e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4

Uji fungsi menggunakan permintaan HTTP

Gunakan alat baris perintah curl untuk menguji titik akhir webhook Anda.

Uji fungsi menggunakan permintaan HTTP
  1. Dalam program terminal atau shell, jalankan perintah curl berikut. Ganti URL dengan nilai untuk titik akhir URL fungsi Anda sendiri dan ganti tanda tangan webhook dengan tanda tangan yang Anda hitung menggunakan kunci rahasia Anda sendiri.

    curl -X POST https://ryqgmbx5xjzxahif6frvzikpre0bpvpf.lambda-url.us-west-2.on.aws/ \ -H "Content-Type: application/json" \ -H "x-webhook-signature: d5f52b76ffba65ff60ea73da67bdf1fc5825d4db56b5d3ffa0b64b7cb85ef48b" \ -d '{"type": "payment.success", "orderId": "1234", "amount": "99.99"}'

    Anda akan melihat output berikut:

    {"received": true}
  2. Periksa CloudWatch log untuk fungsi Anda untuk mengonfirmasinya mengurai muatan dengan benar dengan melakukan hal berikut:

    1. Buka halaman grup Log di CloudWatch konsol Amazon.

    2. Pilih grup log fungsi Anda (/aws/lambda/myLambdaWebhook).

    3. Pilih aliran log yang terbaru.

      Anda akan melihat output yang mirip dengan yang berikut di log fungsi Anda:

      Python
      Processing successful payment for order 1234
      Node.js
      2025-01-10T18:05:42.062Z e54fe6c7-1df9-4f05-a4c4-0f71cacd64f4 INFO Processing successful payment for order 1234
  3. Konfirmasikan bahwa kode Anda mendeteksi tanda tangan yang tidak valid dengan menjalankan perintah curl berikut. Ganti URL dengan titik akhir URL fungsi Anda sendiri.

    curl -X POST https://ryqgmbx5xjzxahif6frvzikpre0bpvpf.lambda-url.us-west-2.on.aws/ \ -H "Content-Type: application/json" \ -H "x-webhook-signature: abcdefg" \ -d '{"type": "payment.success", "orderId": "1234", "amount": "99.99"}'

    Anda akan melihat output berikut:

    {"error": "Invalid signature"}

Bersihkan sumber daya Anda

Sekarang Anda dapat menghapus sumber daya yang Anda buat untuk tutorial ini, kecuali Anda ingin mempertahankannya. Dengan menghapus AWS sumber daya yang tidak lagi Anda gunakan, Anda mencegah tagihan yang tidak perlu ke Anda Akun AWS.

Untuk menghapus fungsi Lambda
  1. Buka halaman Fungsi di konsol Lambda.

  2. Pilih fungsi yang Anda buat.

  3. Pilih Tindakan, Hapus.

  4. Ketik confirm kolom input teks dan pilih Hapus.

Saat Anda membuat fungsi Lambda di konsol, Lambda juga membuat peran eksekusi untuk fungsi Anda.

Untuk menghapus peran eksekusi
  1. Buka halaman Peran dari konsol IAM.

  2. Pilih peran eksekusi yang dibuat Lambda. Peran memiliki format namamyLambdaWebhook-role-<random string>.

  3. Pilih Hapus.

  4. Masukkan nama peran di bidang input teks dan pilih Hapus.