Files
golib/jwt/doc.go

151 lines
5.0 KiB
Go

// Package jwt provides JWT (JSON Web Token) generation and validation with token revocation support.
//
// This package implements JWT access and refresh tokens with the ability to revoke tokens
// using a database-backed blacklist. It supports multiple database backends including
// PostgreSQL, MySQL, SQLite, and MariaDB, and works with both standard library database/sql
// and popular ORMs like GORM and Bun.
//
// # Features
//
// - Access and refresh token generation
// - Token validation with expiration checking
// - Token revocation via database blacklist
// - Support for multiple database types (PostgreSQL, MySQL, SQLite, MariaDB)
// - Compatible with database/sql, GORM, and Bun ORMs
// - Automatic table creation and management
// - Database-native automatic cleanup (PostgreSQL functions, MySQL events)
// - Manual cleanup method for on-demand token cleanup
// - Token freshness tracking for sensitive operations
// - "Remember me" functionality with session vs persistent tokens
//
// # Basic Usage
//
// Create a token generator with database support:
//
// db, _ := sql.Open("postgres", "connection_string")
// gen, err := jwt.CreateGenerator(jwt.GeneratorConfig{
// AccessExpireAfter: 15, // 15 minutes
// RefreshExpireAfter: 1440, // 24 hours
// FreshExpireAfter: 5, // 5 minutes
// TrustedHost: "example.com",
// SecretKey: "your-secret-key",
// DB: db,
// DBType: jwt.DatabaseType{Type: jwt.DatabasePostgreSQL, Version: "15"},
// TableConfig: jwt.DefaultTableConfig(),
// })
//
// Generate tokens:
//
// accessToken, accessExp, err := gen.NewAccess(userID, true, false)
// refreshToken, refreshExp, err := gen.NewRefresh(userID, false)
//
// Validate tokens (using standard library):
//
// tx, _ := db.Begin()
// token, err := gen.ValidateAccess(tx, accessToken)
// if err != nil {
// // Token is invalid or revoked
// }
// tx.Commit()
//
// Validate tokens (using ORM like GORM):
//
// tx := gormDB.Begin()
// token, err := gen.ValidateAccess(tx.Statement.ConnPool, accessToken)
// // or with Bun: gen.ValidateAccess(bunDB.BeginTx(ctx, nil), accessToken)
// tx.Commit()
//
// Revoke tokens:
//
// tx, _ := db.Begin()
// err := token.Revoke(tx)
// tx.Commit()
//
// # Database Configuration
//
// The package automatically creates a blacklist table with the following schema:
//
// CREATE TABLE jwtblacklist (
// jti UUID PRIMARY KEY, -- Token unique identifier
// exp BIGINT NOT NULL, -- Expiration timestamp
// sub INT NOT NULL, -- Subject (user) ID
// created_at TIMESTAMP -- When token was blacklisted
// );
//
// # Cleanup
//
// For PostgreSQL, the package creates a cleanup function that can be called manually
// or scheduled with pg_cron:
//
// SELECT cleanup_jwtblacklist();
//
// For MySQL/MariaDB, the package creates a database event that runs automatically
// (requires event_scheduler to be enabled).
//
// Manual cleanup can be performed at any time:
//
// err := gen.Cleanup(context.Background())
//
// # Using with ORMs
//
// The package works with popular ORMs by using raw SQL queries. For GORM and Bun,
// wrap the underlying *sql.DB with NewDBConnection() when creating the generator:
//
// // GORM example - can use GORM transactions directly
// gormDB, _ := gorm.Open(postgres.Open(dsn), &gorm.Config{})
// sqlDB, _ := gormDB.DB()
// gen, _ := jwt.CreateGenerator(jwt.GeneratorConfig{
// // ... config ...
// DB: sqlDB,
// })
// // Use GORM transaction
// tx := gormDB.Begin()
// token, _ := gen.ValidateAccess(tx.Statement.ConnPool, tokenString)
// tx.Commit()
//
// // Bun example - can use Bun transactions directly
// sqlDB, _ := sql.Open("postgres", dsn)
// bunDB := bun.NewDB(sqlDB, pgdialect.New())
// gen, _ := jwt.CreateGenerator(jwt.GeneratorConfig{
// // ... config ...
// DB: sqlDB,
// })
// // Use Bun transaction
// tx, _ := bunDB.BeginTx(context.Background(), nil)
// token, _ := gen.ValidateAccess(tx, tokenString)
// tx.Commit()
//
// # Token Freshness
//
// Tokens can be marked as "fresh" for sensitive operations. Fresh tokens are typically
// required for actions like changing passwords or email addresses:
//
// token, err := gen.ValidateAccess(exec, tokenString)
// if time.Now().Unix() > token.Fresh {
// // Token is not fresh, require re-authentication
// }
//
// # Custom Table Names
//
// You can customize the blacklist table name:
//
// config := jwt.DefaultTableConfig()
// config.TableName = "my_token_blacklist"
//
// # Disabling Database Features
//
// To use JWT without revocation support (no database):
//
// gen, err := jwt.CreateGenerator(jwt.GeneratorConfig{
// AccessExpireAfter: 15,
// RefreshExpireAfter: 1440,
// FreshExpireAfter: 5,
// TrustedHost: "example.com",
// SecretKey: "your-secret-key",
// DB: nil, // No database
// })
//
// When DB is nil, revocation features are disabled and token validation
// will not check the blacklist.
package jwt