Microservices dan API Gateway: Arsitektur Modern, Contoh Kode, dan Celah Keamanan Header Spoofing
Pendahuluan
Ketika aplikasi monolith mulai sulit di-scale dan dideploy, banyak tim beralih ke microservices architecture. Setiap domain bisnis (user, order, payment) dipecah menjadi service kecil yang independen, punya database sendiri, dan bisa dideploy terpisah. Namun, ada satu masalah baru: klien tidak mungkin menghafal puluhan endpoint berbeda. Di sinilah API Gateway berperan sebagai pintu masuk tunggal (single entry point) yang menangani routing, autentikasi, rate limiting, hingga caching.
Pembahasan
API Gateway bukan sekadar reverse proxy. Tanggung jawab utamanya meliputi:
- Routing — memetakan
/api/orders/*ke order-service. - Authentication & Authorization — memvalidasi JWT sebelum request menyentuh service internal.
- Rate limiting & throttling — mencegah abuse.
- Observability — distributed tracing, logging, dan metrics terpusat.
Pola umum: gateway memverifikasi token, lalu meneruskan identitas user ke service downstream melalui internal header seperti x-user-id. Pola inilah yang paling sering disalahgunakan.
Tips Performa & SEO
Agar API Anda ramah mesin pencari dan cepat: aktifkan response caching di gateway untuk endpoint GET statis, gunakan gzip/brotli compression, sajikan konten publik via CDN, dan pastikan endpoint katalog mengembalikan status 200 (bukan 500 saat service down). Untuk halaman produk, gunakan SSR/ISR agar crawler mendapat HTML lengkap, bukan shell kosong hasil JavaScript.
Contoh Implementasi
Berikut gateway sederhana berbasis Node.js dan http-proxy-middleware. Versi ini rentan:
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const app = express();
const SERVICES = {
'/api/users': 'http://user-service:3001',
'/api/orders': 'http://order-service:3002',
};
Object.entries(SERVICES).forEach(([path, target]) => {
app.use(path, createProxyMiddleware({
target,
changeOrigin: true,
onProxyReq: (proxyReq, req) => {
// RENTAN: header dari klien diteruskan apa adanya
if (req.headers['x-user-id']) {
proxyReq.setHeader('x-user-id', req.headers['x-user-id']);
}
},
}));
});
app.listen(8080);
Analisis Keamanan
Celah: Internal Header Spoofing. Gateway di atas mempercayai header x-user-id yang dikirim klien. Service downstream (misalnya user-service) menganggap header itu berasal dari gateway yang tepercaya, lalu mengembalikan data milik user tersebut tanpa validasi tambahan. Ini adalah varian Broken Object Level Authorization (OWASP API #1).
Demonstrasi eksploitasi:
# Penyerang tidak punya token, cukup menyisipkan header identitas
curl http://api.example.com/api/orders \
-H "x-user-id: 1" \
-H "x-user-role: admin"
{ "orders": [ { "id": 9001, "total": 15000000, "owner": 1 } ] }
Karena gateway meneruskan header tersebut tanpa verifikasi, penyerang bisa membaca data user mana pun hanya dengan mengubah angka pada x-user-id.
Cara Pencegahan
Perbaikan dilakukan dengan tiga prinsip: verify, strip, sign.
const jwt = require('jsonwebtoken');
const GATEWAY_SECRET = process.env.GATEWAY_SECRET;
const INTERNAL_HEADERS = ['x-user-id', 'x-user-role', 'x-internal-token'];
// 1. VERIFY: autentikasi di edge
app.use('/api', (req, res, next) => {
const token = (req.headers.authorization || '').replace('Bearer ', '');
try {
const payload = jwt.verify(token, process.env.JWT_PUBLIC_KEY, {
algorithms: ['RS256'], // cegah algorithm confusion
});
req.user = { id: payload.sub, role: payload.role };
next();
} catch {
res.status(401).json({ error: 'Unauthorized' });
}
});
// 2. STRIP + 3. SIGN: hapus header klien, injeksi ulang
const proxy = createProxyMiddleware({
target: 'http://order-service:3002',
onProxyReq: (proxyReq, req) => {
INTERNAL_HEADERS.forEach((h) => proxyReq.removeHeader(h)); // strip
proxyReq.setHeader('x-user-id', req.user.id);
proxyReq.setHeader('x-user-role', req.user.role);
proxyReq.setHeader('x-internal-token', // sign
jwt.sign({ sub: req.user.id }, GATEWAY_SECRET, { expiresIn: '5s' }));
},
});
Langkah mitigasi tambahan:
- Jalankan service internal di network privat; jangan ekspos ke internet.
- Verifikasi signature
x-internal-tokendi setiap service (zero trust). - Aktifkan rate limiting dan WAF di gateway untuk membatasi enumerasi ID.
- Gunakan mTLS antar-service agar hanya gateway yang boleh memanggil downstream.
- Log dan alert untuk anomali header identitas.
Kesimpulan
API Gateway adalah fondasi microservices architecture yang menangani routing, autentikasi, dan performa—termasuk caching serta compression yang berdampak langsung pada SEO. Namun gateway juga titik kepercayaan (trust boundary) yang paling rawan. Selalu ingat tiga aturan: verifikasi token di edge, strip semua header identitas dari klien, dan tandatangani ulang header internal. Tanpa itu, satu header seperti x-user-id cukup untuk meruntuhkan seluruh model keamanan sistem Anda.