router

package
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 23, 2026 License: MIT Imports: 9 Imported by: 0

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

View Source
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

func DefaultSecurityMiddleware(next http.Handler) http.Handler

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

func MaxRequestBodyMiddleware(maxBytes int64) func(http.Handler) http.Handler

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

func NormalizePathToOpenAPI(path string) string

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

func SecurityHeadersMiddleware(next http.Handler) http.Handler

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(_ 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

type ChiRouter struct {
	*chi.Mux
	// contains filtered or unexported fields
}

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

func NewChiRouter(mux *chi.Mux) *ChiRouter

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.

func (*ChiRouter) Use

func (r *ChiRouter) Use(middleware func(http.Handler) http.Handler)

Use adds middleware to the router. Implements Router.Use by delegating to chi.Mux.Use.

Middleware should follow the func(http.Handler) http.Handler pattern.

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
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL