Documentation
¶
Overview ¶
Package router provides router adapters for the Aegis authentication framework.
This package contains implementations of the Router interface for popular Go HTTP routers, allowing Aegis to integrate with various routing libraries.
Currently supported routers:
- Chi: A lightweight, idiomatic HTTP router for Go
Usage:
mux := chi.NewRouter() router := router.NewChiRouter(mux) aegis.New(ctx, config.WithRouter(router), ...)
Index ¶
- Constants
- func DefaultSecurityMiddleware(next http.Handler) http.Handler
- func MaxRequestBodyMiddleware(maxBytes int64) func(http.Handler) http.Handler
- func MountRoutes(router Router, authService *core.AuthService, config *core.AuthConfig, ...)
- func NormalizePathToOpenAPI(path string) string
- func SecurityHeadersMiddleware(next http.Handler) http.Handler
- type ChiGroupRouter
- func (g *ChiGroupRouter) DELETE(path string, handler http.HandlerFunc)
- func (g *ChiGroupRouter) GET(path string, handler http.HandlerFunc)
- func (g *ChiGroupRouter) Group(path string, groupName string) GroupRouter
- func (g *ChiGroupRouter) PATCH(path string, handler http.HandlerFunc)
- func (g *ChiGroupRouter) POST(path string, handler http.HandlerFunc)
- func (g *ChiGroupRouter) PUT(path string, handler http.HandlerFunc)
- func (g *ChiGroupRouter) RegisterRouteMetadata(metadata core.RouteMetadata)
- func (g *ChiGroupRouter) Use(middleware func(http.Handler) http.Handler)
- type ChiRouter
- func (r *ChiRouter) DELETE(path string, handler http.HandlerFunc)
- func (r *ChiRouter) GET(path string, handler http.HandlerFunc)
- func (r *ChiRouter) GetRouteMetadata() []core.RouteMetadata
- func (r *ChiRouter) Group(path string, groupName string) GroupRouter
- func (r *ChiRouter) PATCH(path string, handler http.HandlerFunc)
- func (r *ChiRouter) POST(path string, handler http.HandlerFunc)
- func (r *ChiRouter) PUT(path string, handler http.HandlerFunc)
- func (r *ChiRouter) RegisterRouteMetadata(metadata core.RouteMetadata)
- func (r *ChiRouter) Use(middleware func(http.Handler) http.Handler)
- type GroupRouter
- type Handlers
- type Router
Constants ¶
const MaxRequestBodySize = 1 << 20 // 1MB
MaxRequestBodySize is the default maximum request body size (1MB).
This limit prevents denial-of-service attacks via extremely large request bodies that could exhaust server memory or network bandwidth.
Adjust this based on your use case:
- API endpoints: 1MB is usually sufficient
- File uploads: Increase to 10MB or more
- Webhooks: May need larger limits depending on payload size
Variables ¶
This section is empty.
Functions ¶
func DefaultSecurityMiddleware ¶
DefaultSecurityMiddleware applies a standard set of security protections.
This is a convenience middleware that combines:
- SecurityHeadersMiddleware (OWASP security headers)
- MaxRequestBodyMiddleware with 1MB limit (DoS protection)
This provides a good security baseline for most applications. Apply this middleware early in your middleware chain (before authentication) to protect all routes.
Usage:
r := chi.NewRouter() r.Use(router.DefaultSecurityMiddleware) r.Use(core.AegisContextMiddleware()) // ... rest of your routes
func MaxRequestBodyMiddleware ¶
MaxRequestBodyMiddleware limits the size of HTTP request bodies.
This middleware wraps the request body with http.MaxBytesReader, which enforces a size limit. If a request exceeds the limit, reading the body will fail and the connection will be closed.
Benefits:
- Prevents memory exhaustion from large requests
- Prevents network bandwidth abuse
- Protects against ZIP bomb attacks
- Limits upload file sizes
Parameters:
- maxBytes: Maximum allowed request body size in bytes
Usage:
// Apply 1MB limit to all routes r.Use(router.MaxRequestBodyMiddleware(1 << 20)) // Apply 10MB limit for file upload routes uploadRouter.Use(router.MaxRequestBodyMiddleware(10 << 20))
func MountRoutes ¶
func MountRoutes(router Router, authService *core.AuthService, config *core.AuthConfig, prefix string, rateLimiter *core.RateLimiter)
MountRoutes mounts all core Aegis authentication routes to the provided router.
This function registers handlers for:
Email+Password Routes (if config.EnableEmailPassword is true):
POST {prefix}/login - Authenticate with email+password
POST {prefix}/signup - Register new account
Protected Routes (require authentication):
POST {prefix}/logout - Invalidate session
GET {prefix}/session - Get current session with user data
GET {prefix}/sessions - List all user sessions
DELETE {prefix}/sessions/:id - Revoke specific session
DELETE {prefix}/sessions - Revoke all sessions
Public Routes:
POST {prefix}/session/refresh - Refresh session with refresh token
Route Grouping:
All core authentication routes are grouped under "Default" for OpenAPI documentation. Session management routes are additionally tagged with "Session".
Note: Route metadata for login/signup is always registered for OpenAPI documentation, but the actual handlers are only mounted when EnableEmailPassword is true. User data is returned with session endpoints, not as a separate /user endpoint.
Rate Limiting:
If a rateLimiter is provided, it's applied to the refresh endpoint to prevent token brute force attacks. Other routes can be rate-limited by plugins or custom middleware.
Parameters:
- router: HTTP router implementing the Router interface
- authService: Core authentication service with all sub-services
- config: Authentication configuration (controls which routes are enabled)
- prefix: URL prefix for all routes (e.g., "/auth", "/api/v1/auth")
- rateLimiter: Optional rate limiter for public endpoints (can be nil)
Example:
router := chi.NewRouter()
authService := core.NewAuthService(...)
config := &core.AuthConfig{EnableEmailPassword: true}
router.MountRoutes(router, authService, config, "/auth", nil)
// Routes mounted:
// POST /auth/login
// POST /auth/signup
// POST /auth/logout
// GET /auth/user
// ... etc
func NormalizePathToOpenAPI ¶
NormalizePathToOpenAPI converts router parameter syntax to OpenAPI path syntax.
Different HTTP routers use different syntax for path parameters:
- Chi, Gin, Echo: /users/:id/posts/:postId
- Gorilla Mux: /users/{id}/posts/{postId}
- OpenAPI spec: /users/{id}/posts/{postId}
This function normalizes paths from :param syntax (chi/gin/echo) to {param} syntax (OpenAPI spec) for automatic API documentation generation.
Conversion rules:
- :id → {id}
- :userId → {userId}
- :post_id → {post_id}
- Parameter names can contain: a-z, A-Z, 0-9, _
Examples:
NormalizePathToOpenAPI("/users/:id")
// Returns: "/users/{id}"
NormalizePathToOpenAPI("/organizations/:orgId/members/:userId")
// Returns: "/organizations/{orgId}/members/{userId}"
NormalizePathToOpenAPI("/static/file.css")
// Returns: "/static/file.css" (unchanged, no parameters)
func SecurityHeadersMiddleware ¶
SecurityHeadersMiddleware adds security headers to all HTTP responses.
This middleware implements OWASP security best practices by adding headers that protect against common web vulnerabilities:
Headers added:
X-Content-Type-Options: nosniff Prevents MIME type sniffing (prevents browsers from interpreting files as different MIME type) Protects against: Drive-by download attacks
X-Frame-Options: DENY Prevents the page from being embedded in <iframe>, <frame>, or <object> Protects against: Clickjacking attacks
X-XSS-Protection: 1; mode=block Enables browser XSS filter (legacy, mostly replaced by CSP) Protects against: Reflected XSS attacks in older browsers
Referrer-Policy: strict-origin-when-cross-origin Controls how much referrer information is sent with requests Protects against: Information leakage via Referer header
Content-Security-Policy: default-src 'self' Basic CSP that only allows resources from the same origin Protects against: XSS, data injection, malicious scripts Note: This is a basic policy - override with custom CSP for your needs
Usage:
r.Use(router.SecurityHeadersMiddleware)
Note: The CSP header can be customized by setting it before this middleware runs, or by using a custom middleware that overrides it.
Types ¶
type ChiGroupRouter ¶
type ChiGroupRouter struct {
// contains filtered or unexported fields
}
ChiGroupRouter wraps a ChiRouter to provide route grouping functionality.
Routes registered on a ChiGroupRouter are automatically prefixed with the group's path and tagged with the group's name for OpenAPI documentation.
ChiGroupRouter is created via ChiRouter.Group() and should not be instantiated directly.
func (*ChiGroupRouter) DELETE ¶
func (g *ChiGroupRouter) DELETE(path string, handler http.HandlerFunc)
DELETE registers a DELETE route handler within this group. The path is automatically prefixed with the group's prefix.
func (*ChiGroupRouter) GET ¶
func (g *ChiGroupRouter) GET(path string, handler http.HandlerFunc)
GET registers a GET route handler within this group. The path is automatically prefixed with the group's prefix.
func (*ChiGroupRouter) Group ¶
func (g *ChiGroupRouter) Group(path string, groupName string) GroupRouter
Group creates a nested group under this group by combining prefixes. The returned GroupRouter uses the same ChiRouter parent so metadata and routes are collected on the same root router.
func (*ChiGroupRouter) PATCH ¶
func (g *ChiGroupRouter) PATCH(path string, handler http.HandlerFunc)
PATCH registers a PATCH route handler within this group. The path is automatically prefixed with the group's prefix.
func (*ChiGroupRouter) POST ¶
func (g *ChiGroupRouter) POST(path string, handler http.HandlerFunc)
POST registers a POST route handler within this group. The path is automatically prefixed with the group's prefix.
func (*ChiGroupRouter) PUT ¶
func (g *ChiGroupRouter) PUT(path string, handler http.HandlerFunc)
PUT registers a PUT route handler within this group. The path is automatically prefixed with the group's prefix.
func (*ChiGroupRouter) RegisterRouteMetadata ¶
func (g *ChiGroupRouter) RegisterRouteMetadata(metadata core.RouteMetadata)
RegisterRouteMetadata registers OpenAPI metadata for a route within this group.
The group's name is automatically added to the Tags field if not already present, ensuring proper categorization in OpenAPI documentation.
func (*ChiGroupRouter) Use ¶
func (g *ChiGroupRouter) Use(middleware func(http.Handler) http.Handler)
Use adds middleware to this group.
Note: Due to chi's routing model, middleware added via Use() on a group affects the parent router. For group-scoped middleware, wrap handlers individually when registering routes.
type ChiRouter ¶
ChiRouter wraps chi.Mux to implement the Router interface.
This adapter allows the popular chi router to be used with Aegis while maintaining the abstraction provided by the Router interface.
Usage:
mux := chi.NewRouter()
mux.Use(middleware.Logger)
router := router.NewChiRouter(mux)
aegis.New(ctx,
config.WithRouter(router),
// ... other options
)
func NewChiRouter ¶
NewChiRouter creates a new ChiRouter that wraps the provided chi.Mux.
The chi.Mux should be configured with any middleware before wrapping, as middleware added via the Router.Use method will be applied to the mux.
Example:
mux := chi.NewRouter() mux.Use(middleware.Logger) mux.Use(middleware.Recoverer) router := router.NewChiRouter(mux)
func (*ChiRouter) DELETE ¶
func (r *ChiRouter) DELETE(path string, handler http.HandlerFunc)
DELETE registers a DELETE route handler. Implements Router.DELETE by delegating to chi.Mux.Delete.
Note: This adapts chi's lowercase Delete method to the uppercase DELETE method required by the Router interface.
func (*ChiRouter) GET ¶
func (r *ChiRouter) GET(path string, handler http.HandlerFunc)
GET registers a GET route handler. Implements Router.GET by delegating to chi.Mux.Get.
func (*ChiRouter) GetRouteMetadata ¶
func (r *ChiRouter) GetRouteMetadata() []core.RouteMetadata
GetRouteMetadata returns all registered route metadata. Used by the OpenAPI plugin to retrieve route documentation.
Implements Router.GetRouteMetadata.
func (*ChiRouter) Group ¶
func (r *ChiRouter) Group(path string, groupName string) GroupRouter
Group creates a sub-router with a prefix for grouping related routes.
Routes registered on the returned GroupRouter will be prefixed with the given path. The groupName is used for OpenAPI documentation categorization.
Example:
jwtGroup := router.Group("/jwt", "JWT")
jwtGroup.POST("/token", tokenHandler) // Mounted at /jwt/token
jwtGroup.POST("/refresh", refreshHandler) // Mounted at /jwt/refresh
Implements Router.Group.
func (*ChiRouter) PATCH ¶
func (r *ChiRouter) PATCH(path string, handler http.HandlerFunc)
PATCH registers a PATCH route handler. Implements Router.PATCH by delegating to chi.Mux.Patch.
func (*ChiRouter) POST ¶
func (r *ChiRouter) POST(path string, handler http.HandlerFunc)
POST registers a POST route handler. Implements Router.POST by delegating to chi.Mux.Post.
func (*ChiRouter) PUT ¶
func (r *ChiRouter) PUT(path string, handler http.HandlerFunc)
PUT registers a PUT route handler. Implements Router.PUT by delegating to chi.Mux.Put.
func (*ChiRouter) RegisterRouteMetadata ¶
func (r *ChiRouter) RegisterRouteMetadata(metadata core.RouteMetadata)
RegisterRouteMetadata stores OpenAPI metadata for a route. This metadata is collected and used by the OpenAPI plugin to generate API documentation automatically.
Implements Router.RegisterRouteMetadata.
type GroupRouter ¶
type GroupRouter interface {
// GET registers a GET route handler within this group
GET(path string, handler http.HandlerFunc)
// POST registers a POST route handler within this group
POST(path string, handler http.HandlerFunc)
// PUT registers a PUT route handler within this group
PUT(path string, handler http.HandlerFunc)
// PATCH registers a PATCH route handler within this group
PATCH(path string, handler http.HandlerFunc)
// DELETE registers a DELETE route handler within this group
DELETE(path string, handler http.HandlerFunc)
// Use adds middleware to this group only
// Middleware is scoped to this group and does not affect parent or sibling routes
Use(middleware func(http.Handler) http.Handler)
// Group creates a nested sub-group within this group.
// Nested groups inherit the parent's prefix and allow further
// organization of routes. The returned GroupRouter is prefixed
// with the nested path and will include the provided groupName
// in route metadata tags when registering routes.
Group(path string, groupName string) GroupRouter
// RegisterRouteMetadata registers OpenAPI metadata for a route within this group
// The groupName is automatically added to the Tags field if not already present
RegisterRouteMetadata(metadata core.RouteMetadata)
}
GroupRouter represents a sub-router for grouping related routes.
GroupRouter provides the same HTTP method registration as Router, but routes are prefixed with the group's path. The groupName is automatically added to route metadata for OpenAPI documentation.
Example:
adminGroup := router.Group("/admin", "Admin")
adminGroup.Use(requireAdminMiddleware)
adminGroup.GET("/users", listUsersHandler)
adminGroup.DELETE("/users/:id", deleteUserHandler)
type Handlers ¶
type Handlers struct {
// contains filtered or unexported fields
}
Handlers provides HTTP handlers for core Aegis authentication routes.
All handlers have been made private (lowercase) to encourage programmatic use of the underlying core services. This struct serves as a mounting point for the router.
func NewHandlers ¶
func NewHandlers(auth *core.AuthService) *Handlers
NewHandlers creates a new Handlers instance with the given AuthService.
type Router ¶
type Router interface {
// GET registers a GET route handler
GET(path string, handler http.HandlerFunc)
// POST registers a POST route handler
POST(path string, handler http.HandlerFunc)
// PUT registers a PUT route handler
PUT(path string, handler http.HandlerFunc)
// PATCH registers a PATCH route handler
PATCH(path string, handler http.HandlerFunc)
// DELETE registers a DELETE route handler
DELETE(path string, handler http.HandlerFunc)
// Use adds middleware to the router
// Middleware should follow the func(http.Handler) http.Handler pattern
Use(middleware func(http.Handler) http.Handler)
// ServeHTTP implements http.Handler for serving requests
ServeHTTP(w http.ResponseWriter, r *http.Request)
// RegisterRouteMetadata registers OpenAPI metadata for a route
// This metadata is used by the OpenAPI plugin for automatic documentation
RegisterRouteMetadata(metadata core.RouteMetadata)
// GetRouteMetadata returns all registered route metadata
// Used by the OpenAPI plugin to generate specifications
GetRouteMetadata() []core.RouteMetadata
// Group creates a sub-router with a prefix for grouping related routes.
// Routes mounted to the returned GroupRouter will be prefixed with the given path.
// The groupName is used for OpenAPI documentation to categorize routes.
//
// Example:
// jwtGroup := router.Group("/jwt", "JWT")
// jwtGroup.POST("/token", tokenHandler) // Mounted at /jwt/token
// jwtGroup.POST("/refresh", refreshHandler) // Mounted at /jwt/refresh
Group(path string, groupName string) GroupRouter
}
Router is the interface for HTTP routers in Aegis.
This abstraction allows Aegis to work with different HTTP routing libraries (chi, mux, gin, echo, etc.) without coupling to a specific implementation.
Implementations must support:
- Standard HTTP methods (GET, POST, PUT, PATCH, DELETE)
- Middleware chain using standard http.Handler interface
- Route metadata registration for OpenAPI documentation
- http.Handler compliance for ServeHTTP
- Route grouping for organizing related routes
Example implementation (using chi):
type ChiRouter struct {
*chi.Mux
metadata []core.RouteMetadata
}
func (r *ChiRouter) RegisterRouteMetadata(m core.RouteMetadata) {
r.metadata = append(r.metadata, m)
}
func (r *ChiRouter) GetRouteMetadata() []core.RouteMetadata {
return r.metadata
}