API Key dan Integrasi Layanan Eksternal — Apa yang Dilindungi Key, dan Webhook

Artikel ini adalah bagian dari kursus Dasar-Dasar Teknologi Informasi, yang membangun dari nol pengetahuan TI praktis yang minimal kamu butuhkan untuk memprogram dan melakukan vibe coding.
API key adalah string yang menunjukkan panggilan itu milik siapa. Diagram memperlihatkan di mana key boleh disimpan dan arah webhook, yaitu request yang dikirim layanan eksternal ke server kamu.

Artikel ini membahas dua hal: API key yang kamu pakai saat memanggil layanan eksternal, dan webhook, yaitu panggilan yang datang dari sisi layanan eksternal.

Kamu akan melihat di mana key diterbitkan, apa yang ditunjukkan string itu, dan di mana menyimpannya supaya tidak ada orang lain yang bisa membacanya.

  • Di mana kamu menerbitkan API key, dan di bagian mana dari panggilan kamu menyertakannya
  • Bahwa key adalah string yang menunjukkan siapa pemilik panggilan, dan kaitannya dengan tagihan berbasis pemakaian
  • Di mana key boleh disimpan, dan apa yang terjadi kalau kamu menuliskannya di tempat yang sampai ke browser
  • Webhook yang dipanggil dari sisi layanan eksternal, dan pencocokan tanda tangan

API key diterbitkan di dashboard layanan eksternal yang kamu pakai

Untuk memanggil layanan eksternal, kamu terlebih dahulu menerima API key dari penyedianya, yaitu string yang memberi tahu penyedia bahwa suatu panggilan itu milik pengguna yang mana.

Nilai ini bukan kamu yang menentukan, melainkan diterbitkan dan diserahkan oleh layanan yang kamu pakai.

Baik untuk pembayaran, peta, maupun pembuatan teks, urutannya tetap sama: daftar, terbitkan key, simpan di server kamu sendiri.

Dari menerbitkan API key sampai menyimpannya di my-app
Situs layananyang dipakaiBuat akunTerdaftar sebagaipenggunaDashboard layananTerbitkan keybaruMenerima satustring panjangServer sendiriTulis di .envBisa disertakandi panggilan
Baca dari atas ke bawah. Kolom kiri adalah tempat kamu bekerja, kolom tengah adalah yang kamu lakukan, dan kolom kanan adalah hasil yang kamu dapat di sana. Key dibuat di dashboard penyedia, dan tempat menyimpannya ada di dalam server kamu sendiri.

Salin string yang diterbitkan itu saat itu juga, lalu simpan di file .env di server kamu sendiri.

Sebagian besar layanan eksternal memakai tagihan berbasis pemakaian (kamu membayar sebanyak yang kamu pakai), dengan perhitungan menurut jumlah panggilan dan volume data yang dikirim dan diterima.

Kalau key bocor, panggilan yang dilakukan orang lain pun masuk ke tagihan pemiliknya.

API key adalah string yang menunjukkan panggilan itu milik pengguna yang mana

API layanan pembayaran adalah URL yang terbuka untuk umum, jadi diperlukan cara untuk mengetahui panggilan yang datang itu milik siapa.

Tempat menyertakannya bukan di URL, melainkan di request header (bagian yang terpisah dari body dan memuat pasangan nama dan nilai seperti pengirim dan format).

Satu request yang dikirim my-app ke layanan pembayaran
Satu request yang dikirim my-app
Baris 1 — method dan URL
  • POST https://api.pay.example.com/v1/charges
  • Hanya berisi tujuan dan apa yang dilakukan di sana
Mulai baris 2 — request header
  • API key ditulis di sini
  • Authorization: Bearer sk_live_a1b2
  • Satu pasangan nama dan nilai per baris
Setelah baris kosong — body
  • Data yang dikirim, dalam bentuk JSON
  • Sering kosong pada panggilan yang hanya mengambil data
Bingkai luar adalah satu request. Menaruh key di URL membuatnya tertinggal di catatan penyedia dan catatan server kamu sendiri, jadi key ditaruh di header di bagian tengah.

Baris kedua di bingkai tengah adalah baris tempat key ditulis.

Authorization adalah nama header-nya, Bearer adalah kata yang menyatakan cara nilainya diserahkan, dan setelahnya adalah nilai key.

Nama maupun cara penulisan ini ditentukan oleh penyedianya.

Dari key yang diterima, layanan pembayaran menentukan 3 hal: pemilik, operasi yang diizinkan, dan jumlah panggilan.

Yang dilakukan my-appHeader AuthorizationYang dilakukan layanan pembayaranYang dikembalikan
Mengambil daftar pembayaranBearer sk_live_a1b2Menentukan pemilik dan memeriksa cakupannya200 dan JSON
Mengambil daftar pembayaranLupa disertakanPemiliknya tidak bisa ditentukan401 dikembalikan
Membuat 1 pembayaranBearer sk_read_9f3cHanya membaca yang diizinkan403 dikembalikan
Memanggil berkali-kali dalam waktu singkatBearer sk_live_a1b2Menghitung jumlah panggilan tiap pemilik429 dikembalikan

Kalau 401, periksa nilai key dan nama header-nya; kalau 403, periksa operasi apa saja yang diizinkan.

Batas pada baris keempat adalah rate limit (jumlah maksimum panggilan yang diterima dalam rentang waktu tertentu), dan kalau dilampaui akan dikembalikan 429.

Key adalah string yang menunjukkan pemilik panggilan

API key adalah string yang tugasnya hanya menyatakan panggilan ini milik siapa.

Layanan pembayaran melihat key itu untuk memastikan pemilik dan operasi yang diizinkan, lalu menghitung jumlah panggilan orang tersebut, sehingga panggilan tanpa key dikembalikan 401, operasi yang tidak diizinkan dikembalikan 403, dan panggilan yang terlalu banyak dikembalikan 429.

Jangan taruh key di kode yang sampai ke browser, simpan hanya di dalam server kamu sendiri

Siapa pun yang memegang key bisa melakukan panggilan atas nama pemiliknya.

Tidak ada layar yang memastikan bahwa orang itu memang pemilik yang sebenarnya.

Ke mana file my-app sampai
Seluruh my-app
Di dalam server sendiri (tidak sampai ke perangkat)
.env
  • PAY_API_KEY=sk_live_a1b2
  • Disimpan di file terpisah dari kode
server.js
  • Menyertakan key yang dibaca dari .env ke panggilan
  • File-nya sendiri tidak dikirim ke perangkat
Yang sampai ke browser (siapa pun bisa membacanya)
  • index.html dan script.js
  • Tidak memanggil layanan pembayaran secara langsung, melainkan meminta lewat server sendiri
  • Hanya memuat key yang diterbitkan untuk dipakai dari browser
File di bingkai atas tidak keluar dari server kamu sendiri. File di bingkai bawah dikirim apa adanya ke perangkat pengguna.

Meski key-nya sama, tempat kamu menuliskannya mengubah siapa saja yang bisa membacanya.

Tempat key ditulisSampai ke perangkat?Siapa yang bisa membacaYang terjadi
.env (di dalam server)Tidak sampaiHanya orang yang bisa mengakses serverBisa dipakai sesuai perjanjian
script.jsSampaiSemua orang yang membuka halamanOrang lain bisa memanggil atas nama kamu
server.js yang dipublikasikanTidak sampai, tetapi terbuka untuk umumSemua orang yang melihat kodenyaTidak bisa dihapus dari riwayat Git

Makin banyak orang yang bisa membaca key di suatu baris, makin besar kemungkinan orang lain bisa memanggil atas nama kamu.

Baris ketiga memang tidak sampai ke browser, tetapi begitu tercatat di Git, isinya tetap bisa dibaca dari riwayat perubahan walaupun nanti dihapus.

Instruksi "masukkan ke .env" pada panduan berarti menyuruh kamu memakai cara penyimpanan di baris pertama.

Ada 2 hal yang bisa kamu lakukan terhadap key yang sudah bocor, dan efeknya tidak sama.

Yang bisa dilakukan terhadap key yang sudah bocor
sk_live_a1b2bocorHapus baris itudari kodeCabut lewatdashboardNilai yang terbacamasih bisa dipakaiPanggilan dengankey itu ditolak
Yang kiri hanya menghapus karakter yang kamu tulis. Yang kanan membuat key itu sendiri tidak bisa dipakai di sisi layanan pembayaran. Hanya yang kanan yang membuat panggilan ditolak.

Nilai yang sudah terbaca orang tetap berlaku, dan nilainya juga tertinggal di riwayat perubahan Git.

Yang kanan adalah pencabutan (revoke, yaitu penyedia membuat key yang sudah diterbitkan menjadi tidak bisa dipakai).

Simpan key hanya di tempat yang tidak sampai ke perangkat

Siapa pun yang memegang key bisa memakainya atas nama pemiliknya.

Karena itu jangan tulis key di file yang sampai ke perangkat pengguna maupun di kode yang kamu publikasikan, dan kalau tanpa sengaja bocor, jangan sekadar menghapus karakter yang kamu tulis, melainkan cabut key itu lalu terbitkan key baru.

Webhook adalah mekanisme saat server kamu sendiri dipanggil dari sisi layanan eksternal

Pembayaran yang selesai atau pengembalian dana adalah peristiwa yang waktunya tidak bisa diketahui pihak pemanggil.

Kalau ditanyakan berulang-ulang, panggilan yang sia-sia bertambah dan kamu pun terlambat menyadarinya.

Webhook (mekanisme saat layanan eksternal mengirim request ke URL yang sudah didaftarkan begitu peristiwa yang ditentukan terjadi) membalik arah ini.

Pihak mana yang mengirim request, pada 3 cara
=CaraPihak yang mengirimYang disiapkanlebih dahuluMemanggil APImy-app →layanan pembayaranEndpoint danAPI keyTanya berulangapakah selesaimy-app →layanan pembayaranJeda bertanyaWebhookLayanan pembayaran→ my-appURL my-app untuknotifikasi
Dua baris teratas arahnya sama, jadi keduanya dihubungkan garis ganda. Hanya webhook yang arahnya dari layanan pembayaran ke my-app.

Hanya webhook di baris ketiga yang arahnya dari layanan pembayaran ke my-app.

Yang perlu disiapkan hanya mendaftarkan 1 URL untuk menerima notifikasi.

Notifikasi yang datang dari 1 kali pembayaran
Pengguna membayar1 kaliPembayaran selesaiKuitansi dibuatDana dikembalikanmy-app/webhooks/payment
Meski hanya 1 kali pembayaran, notifikasi yang datang berbeda untuk tiap peristiwa. Semuanya sampai ke 1 URL yang kamu daftarkan.

Notifikasi yang berbeda datang saat pembayaran selesai, saat kuitansi dibuat, dan saat dana dikembalikan.

Peristiwa mana yang memicu notifikasi itu tertulis di body request.

Panah 1 adalah arah saat kamu yang memanggil, dan panah 2 adalah arah saat layanan eksternal yang memanggil kamu.

Key hanya sampai ke layanan pembayaran dan tidak sampai ke perangkat pengguna.

Webhook adalah panggilan dengan arah terbalik

Webhook adalah panggilan saat my-app dipanggil dari sisi layanan pembayaran.

Gunanya agar peristiwa yang waktunya tidak bisa diketahui langsung dikabarkan begitu terjadi, dan yang perlu disiapkan hanya membuat 1 URL penerima notifikasi lalu mendaftarkannya.

URL penerima notifikasi bisa dipanggil siapa pun, jadi cocokkan tanda tangannya sebelum diproses

URL penerima notifikasi terbuka untuk umum, jadi orang selain layanan pembayaran pun bisa mengirim ke URL yang sama.

Yang mencegah hal ini adalah tanda tangan (signature, yaitu mekanisme menyertakan nilai yang dihitung dari string yang hanya diketahui pengirim dan penerima, lalu penerima mencocokkannya dengan perhitungan yang sama).

Satu notifikasi yang datang dari layanan pembayaran
Satu request yang diterima my-app
Baris 1 — method dan URL
  • POST https://my-app.example.com/webhooks/payment
  • URL yang kamu buat dan daftarkan sendiri
Mulai baris 2 — request header
  • Tanda tangan ditulis di sini
  • ID untuk mengenali notifikasi yang sama sering ada di sini juga
Setelah baris kosong — body
  • Peristiwa mana yang terjadi tertulis dalam JSON
  • ID pembayaran dan statusnya juga ada di sini
Bingkai luar adalah satu request yang datang. Tanda tangan masuk ke header, dan peristiwa mana yang terjadi tertulis di body.

Cocokkan tanda tangan di header sebelum membaca isinya.

Saat keberhasilan tidak dikembalikan, pihak pengirim mengirim notifikasi yang sama sekali lagi, dan itulah pengiriman ulang (retry).

Catat ID tiap notifikasi, lalu lewati yang sudah diproses.

Sama seperti API key, string yang dipakai untuk pencocokan juga tidak ditulis di dalam kode, dan cara menyertakannya kamu pastikan di dokumentasi API.

Kalimat "verifikasi tanda tangannya" pada panduan mengacu pada pencocokan ini.

Cocokkan sebelum membaca, dan bersiap untuk pengiriman kedua

URL penerima notifikasi terbuka untuk umum, jadi kedatangan request saja belum memberi tahu siapa pengirimnya.

Cocokkan tanda tangan sebelum membaca body, dan kalau cocok, perbarui catatannya lalu kembalikan kode status keberhasilan, kemudian ingat ID notifikasi yang sudah diproses supaya pengiriman kedua dilewati.

QUIZ

Cek Pemahaman

Jawab setiap pertanyaan satu per satu.

Soal 1Saat kamu mengirim request dengan API key disertakan, apa yang bisa ditentukan layanan eksternal?

Soal 2Apa masalahnya kalau API key ditulis di kode yang sampai ke browser?

Soal 3Saat notifikasi yang datang lewat Webhook diterima, apa yang dilakukan sebelum membaca isinya?