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 Variable | Deskripsi |
|---|---|
BASE_URL | URL redirect untuk browser request tanpa token |
Security Considerations
- Token Expiration - Token memiliki expiry time (24 jam default)
- HTTPS - Selalu gunakan HTTPS di production
- Token Storage - Jangan simpan token di localStorage, gunakan httpOnly cookies
- Token Refresh - Implementasikan refresh token mechanism