Authentication
Secure your API with built-in authentication middleware.
Basic Auth
go
users := map[string]string{
"admin": "secret123",
"user": "password456",
}
app.Use(middleware.BasicAuth(users))Bearer Token
go
app.Use(middleware.BearerAuth(func(token string) (any, bool) {
user, err := validateJWT(token)
if err != nil {
return nil, false
}
return user, true
}))API Key
Header-based
go
app.Use(middleware.APIKey("X-API-Key", func(key string) (any, bool) {
return db.FindUserByAPIKey(key)
}))Query parameter
go
config := middleware.APIKeyConfig{
Header: "X-API-Key",
Query: "api_key",
Validator: validateKey,
}
app.Use(middleware.APIKeyWithConfig(config))Role-Based Access Control
go
// Require specific role
admin := app.Group("/admin")
admin.Use(middleware.BearerAuth(validateToken))
admin.Use(middleware.RequireRole("admin"))
admin.Get("/dashboard", adminDashboard)Complete Example
go
package main
import (
"github.com/ginjigo/ginji"
"github.com/ginjigo/ginji/middleware"
)
func main() {
app := ginji.New()
// Public routes
public := app.Group("/api/public")
public.Get("/status", getStatus)
// Basic auth routes
basic := app.Group("/api/basic")
basic.Use(middleware.BasicAuth(map[string]string{
"user": "pass",
}))
basic.Get("/profile", getProfile)
// Bearer token routes
protected := app.Group("/api")
protected.Use(middleware.BearerAuth(validateToken))
protected.Get("/users", listUsers)
protected.Post("/users", createUser)
// Admin routes
admin := app.Group("/api/admin")
admin.Use(middleware.BearerAuth(validateToken))
admin.Use(middleware.RequireRole("admin"))
admin.Get("/stats", getStats)
admin.Delete("/users/:id", deleteUser)
// API key routes
external := app.Group("/api/external")
external.Use(middleware.APIKey("X-API-Key", validateAPIKey))
external.Get("/data", getData)
app.Listen(":8080")
}
func validateToken(token string) (any, bool) {
// Validate JWT or session token
// Return user object and validity
return map[string]any{
"id": "123",
"role": "admin",
}, true
}
func validateAPIKey(key string) (any, bool) {
// Validate API key
// Return client info and validity
return map[string]any{
"client": "CompanyA",
}, true
}Custom Validators
LDAP Authentication
go
app.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{
Validator: func(username, password string) bool {
return ldap.Authenticate(username, password)
},
}))Database Validation
go
app.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{
Validator: func(username, password string) bool {
user, err := db.FindUser(username)
if err != nil {
return false
}
return bcrypt.CompareHashAndPassword(
user.PasswordHash,
[]byte(password),
) == nil
},
}))Access User in Handler
go
app.Get("/profile", func(c *ginji.Context) {
// Get authenticated user
user := c.Get("user")
// Or with type assertion
username := c.GetString("user")
c.JSON(ginji.StatusOK, ginji.H{
"user": username,
})
})Custom Context Key
go
config := middleware.BasicAuthConfig{
Users: users,
ContextKey: "authenticated_user",
}
app.Use(middleware.BasicAuthWithConfig(config))
// In handler
user := c.GetString("authenticated_user")Multiple Auth Strategies
go
// Try Bearer first, fall back to API key
app.Use(func(next ginji.Handler) ginji.Handler {
return func(c *ginji.Context) {
// Try Bearer
if token := c.Header("Authorization"); token != "" {
if user, ok := validateBearer(token); ok {
c.Set("user", user)
next(c)
return
}
}
// Try API Key
if key := c.Header("X-API-Key"); key != "" {
if user, ok := validateAPIKey(key); ok {
c.Set("user", user)
next(c)
return
}
}
c.AbortWithStatusJSON(ginji.StatusUnauthorized, ginji.H{
"error": "Authentication required",
})
}
})Security Best Practices
- Use HTTPS - Always in production
- Hash passwords - Use bcrypt or argon2
- Validate tokens - Check expiration and signature
- Use strong secrets - For JWT signing
- Rotate API keys - Periodically
- Rate limit - Prevent brute force
- Audit logs - Track auth attempts
Examples
JWT Validation
go
import "github.com/golang-jwt/jwt/v5"
func validateJWT(tokenString string) (any, bool) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte("your-secret-key"), nil
})
if err != nil || !token.Valid {
return nil, false
}
claims := token.Claims.(jwt.MapClaims)
return claims, true
}With Rate Limiting
go
app.Use(middleware.RateLimitPerMinute(5)) // Limit login attempts
app.Post("/login", loginHandler)Features
- ✅ Basic Auth with constant-time comparison
- ✅ Bearer token support
- ✅ API Key (header or query)
- ✅ Role-based access control
- ✅ Custom validators
- ✅ Flexible context storage
- ✅ Multiple auth strategies
- ✅ WWW-Authenticate headers