Episode ini mengamankan API Go: TLS dengan sertifikat, JWT dan middleware auth, alur OAuth2 serta session, dan praktik keamanan seperti input validation, CORS, rate limiting, dan security headers agar API siap dipakai di internet.

API yang dibangun di episode 10 masih polos: traffic dikirim tanpa enkripsi dan siapa pun bisa mengakses. Di episode 11, kalian akan mengamankan API Go lapis demi lapis, dari transport hingga otorisasi.
Episode 11 membahas empat area keamanan: TLS untuk enkripsi transport, JWT sebagai token otentikasi stateless, alur OAuth2 dan session untuk integrasi dengan provider identitas, serta praktik keamanan API seperti input validation, CORS, rate limiting, dan security headers.
Tanpa TLS, semua data — termasuk kredensial — dikirim sebagai teks polos dan bisa dibaca siapa saja di jalur jaringan. HTTPS mewajibkan enkripsi TLS. Untuk production, dapatkan sertifikat dari Let's Encrypt melalui certbot atau otomatis dari platform cloud.
openssl req -x509 -newkey rsa:4096 -keyout key.pem \
-out cert.pem -days 365 -nodes -subj "/CN=localhost"http.Server bisa melayani TLS dengan ListenAndServeTLS, memakai sertifikat dan kunci privat:
package main
import (
"net/http"
)
func main() {
srv := &http.Server{
Addr: ":8443",
Handler: http.DefaultServeMux,
}
srv.ListenAndServeTLS("cert.pem", "key.pem")
}Di production, jangan pernah meng-komit kunci privat ke repository. Platform seperti Kubernetes menyimpannya sebagai secret atau memakai certificate manager untuk perpanjangan otomatis.
JWT adalah token JSON tiga bagian — header, payload, dan signature — yang ditandatangani sehingga tidak bisa dipalsukan. Payload berisi klaim seperti sub untuk subjek dan exp untuk masa berlaku. Paket populer: github.com/golang-jwt/jwt/v5.
go get github.com/golang-jwt/jwt/v5package main
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
var rahasia = []byte("kunci-sangat-rahasia")
func buatToken(id string) (string, error) {
klaim := jwt.RegisteredClaims{
Subject: id,
ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Hour)),
}
token := jwt.NewWithClaims(jwt.SigningMethodHS256, klaim)
return token.SignedString(rahasia)
}
func main() {
token, err := buatToken("42")
if err != nil {
panic(err)
}
fmt.Println(token)
}Signature dibentuk dari secret yang sama saat verifikasi. Simpan secret di environment variable atau secret manager, bukan di kode.
Verifikasi token dilakukan di middleware: baca header Authorization, cek format Bearer, parse, dan verifikasi signature sebelum melanjutkan ke handler.
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
raw := strings.TrimPrefix(r.Header.Get("Authorization"), "Bearer ")
token, err := jwt.Parse(raw, func(t *jwt.Token) (any, error) {
return rahasia, nil
})
if err != nil || !token.Valid {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}Selalu batasi masa hidup token, jangan simpan token di localStorage untuk aplikasi web, dan gunakan signature yang tepat (HS256 untuk satu server, RS256 untuk distributed). Untuk menguji token yang dihasilkan secara cepat, decode bagian header dan payload dengan jq -R 'split(".")[1] | @base64d' <<< "$TOKEN".
OAuth2 memungkinkan pengguna login dengan akun Google, GitHub, dan lainnya tanpa membagi password. Paket golang.org/x/oauth2 mengelola alur authorization code dengan aman. Access token yang diterima dipakai untuk memanggil provider, dan refresh token untuk memperpanjang sesi.
Untuk aplikasi yang membutuhkan logout dan revoke, session berbasis server lebih cocok daripada JWT. Simpan sesi di Redis atau database dengan masa berlaku, kirimkan ID sesi melalui cookie HttpOnly dan Secure. Cookie HttpOnly mencegah akses dari JavaScript, sehingga mengurangi risiko XSS.
http.SetCookie(w, &http.Cookie{
Name: "session_id",
Value: sid,
HttpOnly: true,
Secure: true,
Path: "/",
SameSite: http.SameSiteStrictMode,
})Jangan pernah percaya input pengguna. Validasi setiap field — panjang, format, dan tipe — sebelum diproses. Library seperti go-playground/validator menyederhanakan validasi struct dengan tag:
type LoginRequest struct {
Email string `validate:"required,email"`
Password string `validate:"required,min=8"`
}CORS membatasi domain mana yang boleh memanggil API dari browser. Rate limiting membatasi jumlah request per klien per waktu untuk mencegah penyalahgunaan dan brute-force. Untuk production, terapkan rate limiting terpusat seperti Redis bersama golang.org/x/time/rate atau middleware khusus.
Selalu kirim header keamanan di setiap respons: Content-Security-Policy untuk membatasi sumber konten, X-Content-Type-Options: nosniff untuk mencegah MIME sniffing, dan Strict-Transport-Security untuk memaksa HTTPS. Kombinasi header ini menaikkan level keamanan aplikasi secara drastis dengan biaya hampir nol.
Episode 11 mengamankan API Go dari transport hingga lapisan aplikasi: TLS dengan ListenAndServeTLS, JWT dengan golang-jwt dan middleware otorisasi, alur OAuth2 dan session berbasis cookie aman, serta praktik input validation, CORS, rate limiting, dan security headers.
Inti yang harus dibawa pulang:
Di episode 12 selanjutnya kita akan membahas concurrency, context, dan safe parallelism — goroutine, channel, dan select sebagai primitive concurrency, context.Context untuk cancellation dan deadline, serta sinkronisasi dengan sync.Mutex, WaitGroup, Once, dan atomic operations. Ini identitas paling khas dari Go.