Belajar Echo - Autentikasi & Otorisasi
Series/Belajar Echo/Episode 13
Episode 13 of 23

Belajar Echo - Autentikasi & Otorisasi

Episode ini membangun kontrol akses: JWT dengan middleware.JWT, Basic Auth, session cookie, refresh token, middleware RBAC untuk otorisasi berbasis peran, serta integrasi OAuth2 dan OpenID Connect dengan Keycloak beserta konsep scopes.

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

Pendahuluan

Autentikasi menjawab "siapa kamu", otorisasi menjawab "apa yang boleh kamu lakukan". Keduanya adalah garis pertahanan pertama API kalian. Echo menyediakan middleware yang memangkas banyak pekerjaan manual, tapi memahami alurnya tetap wajib.

Episode 13 ini membangun kontrol akses: JWT dengan middleware.JWT, Basic Auth, session cookie, refresh token, middleware RBAC untuk kontrol peran, serta integrasi OAuth2 dan OpenID Connect dengan Keycloak.

Autentikasi JWT

Middleware JWT Bawaan

middleware.JWT memvalidasi token di setiap request yang kalian lindungi. Token diambil dari header Authorization dalam format Bearer <token>:

Memasang middleware JWT
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
	SigningKey: []byte(cfg.JWTSecret),
	ContextKey: "user",
}))

Echo v5 mendukung github.com/golang-jwt/jwt/v5. Saat token valid, klaim token disimpan di context dengan key user dan bisa diambil lewat c.Get("user").

Membaca Klaim dan Membuat Token

Buat token saat login, lalu baca klaim di handler:

Membuat JWT saat login
func loginHandler(c echo.Context) error {
	claims := jwt.MapClaims{
		"sub":  user.ID,
		"role": user.Role,
		"exp":  time.Now().Add(time.Hour).Unix(),
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	signed, err := token.SignedString([]byte(cfg.JWTSecret))
	if err != nil {
		return err
	}
	return c.JSON(http.StatusOK, map[string]string{"token": signed})
}

Di handler lain, ambil identitas user:

Membaca klaim dari context
func profileHandler(c echo.Context) error {
	user := c.Get("user").(*jwt.Token)
	claims := user.Claims.(jwt.MapClaims)
	role := claims["role"].(string)
	return c.JSON(http.StatusOK, map[string]string{"role": role})
}

c.Get("user") mengambil token yang sudah divalidasi middleware JWT. Klaim seperti role tersedia untuk keputusan otorisasi.

Basic Auth untuk Kasus Sederhana

Untuk service internal atau endpoint administrasi, Basic Auth cukup:

Basic Auth untuk group admin
admin := e.Group("/admin", middleware.BasicAuth(func(user, pass string, c echo.Context) (bool, error) {
	return user == "admin" && pass == cfg.AdminPassword, nil
}))

middleware.BasicAuth membandingkan kredensial dari header. Ingat: Basic Auth mengirim kredensial dalam bentuk base64 — hanya aman di atas HTTPS.

Untuk aplikasi web klasik, session berbasis cookie adalah pilihan alami. Simpan session ID di cookie, dan datanya di store (memori, database, atau Redis):

Membuat session cookie
c.SetCookie(&http.Cookie{
	Name:     "session",
	Value:    sessionID,
	Path:     "/",
	HttpOnly: true,
	Secure:   true,
	SameSite: http.SameSiteStrictMode,
})

HttpOnly mencegah JavaScript membaca cookie, Secure memastikan hanya dikirim lewat HTTPS, dan SameSiteStrictMode mencegah serangan CSRF.

Refresh Token

Memperpanjang Sesi Tanpa Login Ulang

Access token berumur pendek; refresh token berumur panjang digunakan untuk mendapatkan access token baru:

Handler refresh token
func refreshHandler(c echo.Context) error {
	refresh := c.Get("user").(*jwt.Token)
	claims := refresh.Claims.(jwt.MapClaims)
	sub := claims["sub"].(string)
	newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
		"sub": sub,
		"exp": time.Now().Add(time.Hour).Unix(),
	})
	signed, err := newToken.SignedString([]byte(cfg.JWTSecret))
	if err != nil {
		return err
	}
	return c.JSON(http.StatusOK, map[string]string{"token": signed})
}

Simpan refresh token di tempat aman (misal di penyimpanan server), batasi masa berlakunya, dan beri kemampuan revoke bila dicurigai bocor.

Otorisasi RBAC

Middleware Berbasis Peran

JWT sudah membawa peran; kini buat middleware yang memeriksa peran sebelum handler berjalan:

Middleware RBAC sederhana
func requireRole(roles ...string) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			user := c.Get("user").(*jwt.Token)
			claims := user.Claims.(jwt.MapClaims)
			role := claims["role"].(string)
			for _, r := range roles {
				if role == r {
					return next(c)
				}
			}
			return echo.NewHTTPError(http.StatusForbidden, "peran tidak diizinkan")
		}
	}
}

Pasang middleware ini di route yang butuh hak khusus:

Route yang butuh peran admin
adminOnly := e.Group("/admin")
adminOnly.Use(requireRole("admin"))
adminOnly.DELETE("/users/:id", deleteUser)

Route di group /admin hanya bisa diakses user dengan peran admin; lainnya mendapat 403.

OAuth2 dan OpenID Connect

Integrasi dengan Keycloak

Untuk ekosistem enterprise, serahkan autentikasi ke Identity Provider seperti Keycloak lewat OAuth2 dan OpenID Connect. Arahkan middleware JWT Echo ke JWKS Keycloak:

Verifikasi token dari Keycloak
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
	SigningKey: []byte(cfg.KeycloakPublicKey),
	Claims:     jwt.MapClaims{},
}))

Konsep scopes menentukan hak akses yang diberikan: token dari Keycloak membawa claim scope berisi cakupan seperti profile atau email. Middleware RBAC di atas bisa diperluas untuk memeriksa scopes selain peran.

Penutup

Episode 13 membangun kontrol akses lengkap: JWT dengan middleware.JWT untuk API stateless, Basic Auth untuk kasus sederhana, session cookie untuk aplikasi web, refresh token untuk memperpanjang sesi, middleware RBAC untuk kontrol peran, dan integrasi OAuth2 dengan Keycloak untuk skala enterprise.

Inti yang harus dibawa pulang:

  • middleware.JWT memvalidasi token dan menyimpan klaim di context.
  • Jangan pernah hardcode secret JWT; baca dari environment.
  • Basic Auth hanya aman di atas HTTPS.
  • Session cookie wajib HttpOnly, Secure, dan SameSite.
  • Refresh token memperpanjang sesi tanpa login ulang.
  • Middleware RBAC memeriksa peran sebelum mengizinkan akses.
  • Keycloak menyediakan OAuth2 dan OIDC dengan claim scope.

Di episode 14 selanjutnya kita akan membahas security middleware & input hardening — konfigurasi CORS ketat, security headers seperti CSP dan HSTS, CSRF, BodyLimit, rate limiting, validasi input ketat, sanitasi, serta pencegahan injection, SSRF, dan proteksi sensitive headers.

Belajar Echo - Autentikasi & Otorisasi | Belajar Echo