Skip to main content

Auth Middleware

Dokumentasi JWT authentication middleware.

Overview

AuthMiddleware adalah Gin middleware yang menangani autentikasi JWT token untuk protected routes.

Function Signature

func AuthMiddleware() gin.HandlerFunc

Flow Diagram

┌─────────────┐     ┌──────────────────┐     ┌─────────────────┐
│ Request │────▶│ Check Auth Header│────▶│ Header Empty? │
└─────────────┘ └──────────────────┘ └────────┬────────┘

┌────────────────────────────┼────────────────────────────┐
│ │ │
▼ YES │ │
┌──────────────────────┐ │ │
│ Detect Request Type │ │ │
│ (API or Browser) │ │ │
└──────────┬───────────┘ │ │
│ │ │
┌───────────────┼───────────────┐ │ │
│ │ │ │ │
▼ API ▼ Browser │ │ │
┌─────────────────┐ ┌─────────────────┐ │ │ │
│ Return JSON │ │ Redirect to │ │ │ │
│ 401 Error │ │ Login Page │ │ │ │
└─────────────────┘ └─────────────────┘ │ │ │
│ │ NO │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Extract Token │ │
│ │ from Header │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ Verify Token │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────┼────────┐ │
│ │ │ │ │
│ ▼ VALID ▼ INVALID │
│ ┌───────┐ ┌──────────────┐ │
│ │ Next()│ │ Same as │ │
│ │ │ │ Empty Header │ │
│ └───────┘ └──────────────┘ │
└─────────────────────────────────────────┘

Request Type Detection

Middleware dapat mendeteksi apakah request berasal dari:

  • API Client (Postman, cURL, Swagger, Mobile App)
  • Browser (Direct URL access)

Detection Logic

isAPIRequest := strings.Contains(accept, "application/json") ||
(strings.Contains(accept, "*/*") && !strings.Contains(accept, "text/html")) ||
strings.Contains(userAgent, "Swagger") ||
strings.Contains(userAgent, "curl") ||
strings.Contains(userAgent, "Postman") ||
strings.Contains(userAgent, "Mozilla/5.0") && strings.Contains(referer, "swagger") ||
strings.Contains(contentType, "application/json") ||
strings.HasPrefix(c.Request.URL.Path, "/swagger/") ||
strings.HasPrefix(c.Request.URL.Path, "/docs/") ||
c.Request.Header.Get("X-Requested-With") == "XMLHttpRequest"

Token Format

Token dikirim melalui Authorization header dengan format khusus:

Authorization: xxx<JWT_TOKEN>xxxxx
note

Token di-wrap dengan prefix xxx dan suffix xxxxx. Middleware akan mengekstrak token asli dengan menghapus 3 karakter pertama dan 5 karakter terakhir.

Context Values

Setelah autentikasi berhasil, middleware menyimpan userID ke Gin context:

c.Set("userID", claims.UserID)

Mengakses UserID di Controller

func GetProfile(c *gin.Context) {
userID := c.GetString("userID")
// atau
userID, exists := c.Get("userID")
}

Error Responses

API Request - No Token

{
"error": "Authorization header is required"
}

API Request - Invalid Token

{
"error": "Invalid token"
}

Browser Request

Redirect ke BASE_URL (login page).

Usage

Apply to Route Group

protected := router.Group("/api/v1")
protected.Use(middleware.AuthMiddleware())
{
protected.GET("/profile", controllers.GetProfile)
protected.GET("/users", controllers.GetUsers)
}

Skip for Specific Routes

router.POST("/api/v1/auth/login", controllers.Login)  // No middleware
router.POST("/api/v1/auth/register", controllers.Register) // No middleware

protected := router.Group("/api/v1")
protected.Use(middleware.AuthMiddleware())
{
protected.GET("/profile", controllers.GetProfile) // With middleware
}

Configuration

Environment VariableDeskripsi
BASE_URLURL redirect untuk browser request tanpa token

Security Considerations

  1. Token Expiration - Token memiliki expiry time (24 jam default)
  2. HTTPS - Selalu gunakan HTTPS di production
  3. Token Storage - Jangan simpan token di localStorage, gunakan httpOnly cookies
  4. Token Refresh - Implementasikan refresh token mechanism