// 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