Belajar Golang - Keamanan API, TLS, dan Otentikasi
Episode 11 of 19

Belajar Golang - Keamanan API, TLS, dan Otentikasi

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.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

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.

TLS dan Sertifikat

Mengapa HTTPS

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.

Membuat sertifikat lokal
openssl req -x509 -newkey rsa:4096 -keyout key.pem \
  -out cert.pem -days 365 -nodes -subj "/CN=localhost"

Melayani HTTPS di net/http

http.Server bisa melayani TLS dengan ListenAndServeTLS, memakai sertifikat dan kunci privat:

Server HTTPS
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.

Otentikasi dengan JWT

Struktur JWT

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.

Menambah golang-jwt
go get github.com/golang-jwt/jwt/v5

Menerbitkan dan Memverifikasi Token

Membuat JWT
package 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.

Middleware Otorisasi

Verifikasi token dilakukan di middleware: baca header Authorization, cek format Bearer, parse, dan verifikasi signature sebelum melanjutkan ke handler.

Middleware JWT
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 dan Session

OAuth2 untuk Delegasi Identitas

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.

Session Berbasis Server

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.

Cookie aman
http.SetCookie(w, &http.Cookie{
	Name:     "session_id",
	Value:    sid,
	HttpOnly: true,
	Secure:   true,
	Path:     "/",
	SameSite: http.SameSiteStrictMode,
})

Praktik Keamanan API

Input Validation

Jangan pernah percaya input pengguna. Validasi setiap field — panjang, format, dan tipe — sebelum diproses. Library seperti go-playground/validator menyederhanakan validasi struct dengan tag:

Validasi dengan tag
type LoginRequest struct {
	Email    string `validate:"required,email"`
	Password string `validate:"required,min=8"`
}

CORS dan Rate Limiting

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.

Security Headers

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.

Penutup

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:

  • TLS mengenkripsi transport; jangan pernah mengirim kredensial tanpa HTTPS.
  • JWT adalah token stateless bertanda tangan dengan masa berlaku.
  • Batasi TTL token dan simpan secret di secret manager.
  • Session server memudahkan logout dan revoke.
  • Validasi semua input; header keamanan dipasang di setiap respons.
  • Rate limiting melindungi API dari penyalahgunaan dan brute-force.

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.

Belajar Golang - Keamanan API, TLS, dan Otentikasi | Belajar Golang