Episode ini mengamankan aplikasi kalian: secure coding dengan validasi input dan escaping, pencegahan injeksi SQL, pola autentikasi dan otorisasi dengan JWT dan OAuth2, perlindungan CSRF dan CORS, serta scanning keamanan dependency dan risiko supply-chain.

Keamanan bukan fitur yang ditambahkan di akhir — ia keputusan desain di setiap lapisan. Episode 14 membekali kalian dengan best practice keamanan yang diadopsi tim produksi: menulis kode aman, mencegah injeksi, mengamankan autentikasi, dan menjaga rantai dependency.
Kita akan mengikuti prinsip OWASP, membahas JWT dan OAuth2, serta CSRF dan CORS. Tujuannya satu: API kalian tidak mudah dieksploitasi oleh serangan yang paling umum.
Aturan pertama keamanan: jangan pernah percaya input pengguna. Setiap input melewati trust boundary dan harus divalidasi. FastAPI dengan pydantic sudah membantu:
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field
app = FastAPI()
class Pengguna(BaseModel):
email: EmailStr
usia: int = Field(ge=13, le=120)
@app.post("/pengguna")
def buat_pengguna(data: Pengguna):
return {"email": data.email}EmailStr memvalidasi format email dan Field(ge=13, le=120) membatasi rentang usia. Validasi di layer input mencegah data berbahaya masuk lebih dalam ke sistem. Jangan pernah menunda validasi ke layer lain.
SQL injection terjadi saat input pengguna disambungkan langsung ke query SQL:
nama = "admin' OR '1'='1"
query = f"SELECT * FROM pengguna WHERE nama = '{nama}'"
print("query rentan:", query)f"SELECT * FROM pengguna WHERE nama = '{nama}'" menyambungkan input langsung ke SQL. Dengan input di atas, query selalu mengembalikan semua baris — kebocoran data serius. Ini pola yang wajib dihindari.
Solusinya adalah parameterized query atau binding parameter:
from sqlalchemy import create_engine, text
engine = create_engine("sqlite:///belajar.db")
with engine.connect() as conn:
hasil = conn.execute(
text("SELECT * FROM pengguna WHERE nama = :nama"),
{"nama": "Arman"},
)
print(hasil.fetchall())text("SELECT * FROM pengguna WHERE nama = :nama") memakai placeholder :nama dan nilai dikirim terpisah di dict. Database memperlakukan nilai sebagai data, bukan perintah SQL. Selalu pakai parameterized query — tidak ada alasan untuk memakai f-string di SQL.
JWT (JSON Web Token) adalah standar token autentikasi:
pip install pyjwtimport jwt
from datetime import datetime, timedelta
rahasia = "kunci-rahasia-anda"
token = jwt.encode(
{"sub": "user-123", "exp": datetime.now() + timedelta(hours=1)},
rahasia,
algorithm="HS256",
)
print(token)
decode = jwt.decode(token, rahasia, algorithms=["HS256"])
print(decode["sub"])jwt.encode(payload, rahasia, algorithm="HS256") membuat token dengan klaim sub dan exp. jwt.decode memverifikasi tanda tangan dan kedaluwarsa. Token ini dikirim klien di header Authorization untuk akses endpoint terproteksi.
OAuth2 adalah protokol untuk memberikan akses tanpa berbagi password. FastAPI memiliki dukungan bawaan:
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")OAuth2PasswordBearer(tokenUrl="token") mengonfigurasi flow OAuth2 password. Klien mengirim kredensial ke /token, menerima access token, lalu memakainya di endpoint terproteksi. Untuk kebutuhan produksi penuh, pertimbangkan provider seperti Auth0 atau Keycloak.
CSRF memaksa browser pengguna mengirim request yang tidak diinginkan. Framework menyediakan perlindungan:
X-CSRFToken: token-unik-per-sesiProtection CSRF umumnya menambahkan token unik per sesi yang harus dikirim bersama request. Django dan framework lain menyediakan middleware ini. Aktifkan selalu untuk aplikasi yang memakai cookie autentikasi.
CORS mengontrol domain mana yang boleh memanggil API kalian:
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=["https://aplikasi-anda.com"],
allow_methods=["GET", "POST"],
allow_headers=["Authorization"],
)CORSMiddleware(allow_origins=["https://aplikasi-anda.com"]) membatasi asal request yang diizinkan. Jangan memakai allow_origins=["*"] di production — itu membuka API ke semua domain. Konfigurasi CORS yang ketat mengurangi risiko serangan cross-origin.
Dependency yang kalian install bisa mengandung kerentanan. Scan rutin dengan pip-audit:
pip install pip-audit
pip-auditpip-audit memindai package yang terinstall terhadap database CVE dan melaporkan kerentanan yang ditemukan. Jalankan di lokal dan di CI/CD untuk menjaga dependency tetap aman sepanjang waktu.
Inti yang harus dibawa pulang:
Di episode 15 selanjutnya kita akan membahas concurrency dan parallelism — threading, multiprocessing, dan asyncio, model dan jebakan masing-masing, pola async modern dengan TaskGroups di Python 3.11, serta alternatif trio dan anyio. API kalian akan berjalan lebih cepat dan efisien!