Stateless Guard (JWT/PASETO)
Stateless authentication uses self-contained tokens (JWT or PASETO) to carry user identity. This allows the server to verify the user without querying the database or cache on every request, making it ideal for distributed systems and mobile apps.
Concept
When a user logs in, the server generates a signed token. The client stores this token (e.g., in localStorage or a secure cookie) and sends it in the Authorization: Bearer <token> header for subsequent requests. The server verifies the signature and extracts the user ID from the token payload.
Configuration
Configure the stateless guard in your config/auth.go and populate settings via .env:
AUTH_TOKEN_DRIVER=paseto # jwt or paseto
AUTH_TOKEN_SECRET=your-32-character-secret
AUTH_TOKEN_EXPIRES_IN=24h
Drivers
JWT Driver
Industry standard. Uses HMAC-SHA256 (HS256) for signing. Widely compatible but requires careful secret management.
PASETO Driver
Modern, secure-by-default alternative (V4 Local). Avoids common JWT pitfalls like "alg: none" or algorithm confusion.
Setup
Initialize the guard in your application boot process (e.g., bin/server.go):
func bootStatelessAuth(app *nimbus.App) {
var driver auth.TokenDriver
if config.Auth.Stateless.Driver == "paseto" {
driver = auth.NewPasetoDriver(config.Auth.Stateless.Secret)
} else {
driver = auth.NewJWTDriver(config.Auth.Stateless.Secret)
}
// UserLoader is used only after token validation to load the actual model from DB
guard := auth.NewStatelessGuard(driver, models.UserByID(database.DB))
app.Container.Singleton("auth.stateless", func() *auth.StatelessGuard {
return guard
})
}
Usage
Generating Tokens
guard := app.Container.MustMake("auth.stateless").(*auth.StatelessGuard)
// Generate token for user ID 123
token, err := guard.GenerateToken("123", 24 * time.Hour)
Middleware Protection
Register the middleware in your start/kernel.go and use it on your routes:
// In kernel.go
Middleware["auth:api"] = auth.RequireStatelessToken(guard)
// In routes.go
api := app.Router.Group("/api", Middleware["auth:api"])
api.Get("/profile", ProfileHandler)
Security Best Practices
- Use PASETO: Favor PASETO over JWT for new applications.
- Rotate Secrets: Change your
AUTH_TOKEN_SECRETregularly. Changing it will invalidate all existing tokens (global logout). - Short Expirations: Use short-lived tokens and implement refresh token logic for improved security.
- Secure Storage: If storing tokens in cookies, always use
HttpOnlyandSecureflags.