M
Mr Sugiarto
Developer
27 Aug 2026 3 min read

Di Part 8 kita sudah bisa register, login, dan mendapatkan access token. Tapi sampai sekarang token itu belum benar-benar dipakai untuk apapun — endpoint CRUD Post masih bisa diakses siapa saja tanpa token. Di part ini kita buat middleware yang memvalidasi JWT dan memproteksi endpoint yang sifatnya mengubah data.

Membuat Middleware

Buat file middleware/auth.go:

package middleware

import (
	"strings"

	"github.com/gofiber/fiber/v2"

	"blogfiber/auth"
)

func AuthRequired(c *fiber.Ctx) error {
	header := c.Get("Authorization")
	if header == "" {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
			"message": "token tidak ditemukan",
		})
	}

	parts := strings.SplitN(header, " ", 2)
	if len(parts) != 2 || !strings.EqualFold(parts[0], "Bearer") {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
			"message": "format token tidak valid, gunakan: Bearer <token>",
		})
	}

	claims, err := auth.ParseAccessToken(parts[1])
	if err != nil {
		return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{
			"message": "token tidak valid atau sudah kadaluarsa",
		})
	}

	c.Locals("user_id", claims.UserID)

	return c.Next()
}

Alur middleware ini:

  1. Ambil header Authorization dari request.
  2. Pastikan formatnya Bearer <token>.
  3. Verifikasi token pakai auth.ParseAccessToken (yang sudah kita buat di Part 8) — kalau signature tidak cocok atau token sudah expired, ditolak dengan 401.
  4. Kalau valid, simpan user_id dari klaim token ke c.Locals("user_id", ...) supaya bisa diakses oleh handler berikutnya.
  5. Panggil c.Next() untuk melanjutkan ke handler tujuan.

Di Fiber, sebuah handler yang memanggil c.Next() (atau tidak memanggilnya sama sekali untuk menghentikan request) berperan sebagai middleware — tidak ada tipe khusus, cukup fungsi dengan signature func(*fiber.Ctx) error seperti handler biasa.

Menerapkan Middleware ke Route

Middleware bisa didaftarkan langsung sebagai argumen tambahan sebelum handler pada route tertentu. Update routes/routes.go:

posts := api.Group("/posts")
posts.Get("/", postHandler.Index)
posts.Get("/:id", postHandler.Show)
posts.Post("/", middleware.AuthRequired, postHandler.Create)
posts.Put("/:id", middleware.AuthRequired, postHandler.Update)
posts.Delete("/:id", middleware.AuthRequired, postHandler.Delete)

Kita sengaja hanya memproteksi Create, Update, dan Delete — endpoint Index dan Show tetap publik supaya siapa saja bisa membaca daftar/detail post tanpa perlu login, mirip pola read-public/write-protected yang umum dipakai di API blog.

Testing

Coba akses endpoint yang diproteksi tanpa token:

curl -i -X POST http://127.0.0.1:3000/api/v1/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"Test","slug":"test","body":"body"}'

Akan dibalas 401 Unauthorized dengan pesan token tidak ditemukan.

Login dulu untuk dapat token, lalu sertakan di header Authorization:

TOKEN=$(curl -s -X POST http://127.0.0.1:3000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"budi@example.com","password":"rahasia123"}' | jq -r .access_token)

curl -X POST http://127.0.0.1:3000/api/v1/posts \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"title":"Test With Token","slug":"test-with-token","body":"body"}'

Kali ini request berhasil dan post tersimpan. Coba juga kirim token yang salah/rusak — middleware akan menolak dengan 401 token tidak valid atau sudah kadaluarsa. Sementara endpoint GET /api/v1/posts tetap bisa diakses tanpa token sama sekali.

Endpoint CRUD kita sekarang sudah punya proteksi dasar. Tapi access token kita berumur pendek (15 menit) — di part berikutnya kita akan tambahkan refresh token supaya user tidak perlu login ulang setiap 15 menit, plus endpoint logout.

M
Mr Sugiarto

Developer

Bagian dari Series: GoFiber Dasar - Belajar Fundamental Lewat REST API Blog

Belajar konsep-konsep dasar GoFiber (routing, handler, GORM, MySQL, JWT auth) dengan membangun REST API blog sederhana dari nol - lengkap dengan auten...

Lihat Series Lengkap