Update JWT documentation for new database interface
Updated all examples to reflect the simplified database API that uses *sql.DB and *sql.Tx directly instead of custom wrapper interfaces. Changes: - Changed GeneratorConfig.DBConn to GeneratorConfig.DB (*sql.DB) - Updated all transaction examples to use db.Begin() directly - Removed references to jwt.NewDBConnection() wrapper - Fixed GORM example to show correct usage with sqlDB - Corrected Bun example - sql.DB should be created first, then passed to both Bun and JWT generator (previously showed incorrect usage) - Updated complete example with proper transaction handling - Simplified API makes it clearer how to integrate with ORMs 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
66
JWT.md
66
JWT.md
@@ -47,7 +47,7 @@ func main() {
|
||||
FreshExpireAfter: 5, // Tokens stay fresh for 5 minutes
|
||||
TrustedHost: "example.com",
|
||||
SecretKey: "your-secret-key-here",
|
||||
DBConn: jwt.NewDBConnection(db),
|
||||
DB: db,
|
||||
DBType: jwt.DatabaseType{
|
||||
Type: jwt.DatabasePostgreSQL,
|
||||
Version: "15",
|
||||
@@ -92,7 +92,7 @@ type GeneratorConfig struct {
|
||||
SecretKey string // Secret key for token signing
|
||||
|
||||
// Optional fields (for database support)
|
||||
DBConn DBConnection // Database connection (nil to disable revocation)
|
||||
DB *sql.DB // Database connection (nil to disable revocation)
|
||||
DBType DatabaseType // Database type and version
|
||||
TableConfig TableConfig // Table configuration
|
||||
}
|
||||
@@ -162,10 +162,8 @@ token, expiry, err := gen.NewRefresh(42, true)
|
||||
Tokens must be validated within a transaction context:
|
||||
|
||||
```go
|
||||
import "context"
|
||||
|
||||
// Begin transaction
|
||||
tx, err := gen.dbConn.BeginTx(context.Background(), nil)
|
||||
tx, err := db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -209,9 +207,7 @@ ttl := token.TTL // "session" or "exp"
|
||||
### Revoking a Token
|
||||
|
||||
```go
|
||||
import "context"
|
||||
|
||||
tx, _ := gen.dbConn.BeginTx(context.Background(), nil)
|
||||
tx, _ := db.Begin()
|
||||
defer tx.Rollback()
|
||||
|
||||
// Validate token first
|
||||
@@ -247,7 +243,7 @@ Tokens can be marked as "fresh" for sensitive operations:
|
||||
accessToken, _, _ := gen.NewAccess(userID, true, false) // fresh=true
|
||||
|
||||
// Check freshness
|
||||
tx, _ := gen.dbConn.BeginTx(context.Background(), nil)
|
||||
tx, _ := db.Begin()
|
||||
defer tx.Rollback()
|
||||
|
||||
token, _ := gen.ValidateAccess(tx, accessToken)
|
||||
@@ -364,8 +360,8 @@ CREATE INDEX IF NOT EXISTS idx_jwtblacklist_sub ON jwtblacklist(sub);
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/driver/postgres"
|
||||
)
|
||||
|
||||
// Get underlying *sql.DB from GORM
|
||||
@@ -374,12 +370,21 @@ sqlDB, _ := gormDB.DB()
|
||||
|
||||
// Create generator with sql.DB
|
||||
gen, _ := jwt.CreateGenerator(jwt.GeneratorConfig{
|
||||
// ... config
|
||||
DBConn: jwt.NewDBConnection(sqlDB),
|
||||
AccessExpireAfter: 15,
|
||||
RefreshExpireAfter: 1440,
|
||||
FreshExpireAfter: 5,
|
||||
TrustedHost: "example.com",
|
||||
SecretKey: "your-secret-key",
|
||||
DB: sqlDB,
|
||||
DBType: jwt.DatabaseType{
|
||||
Type: jwt.DatabasePostgreSQL,
|
||||
Version: "15",
|
||||
},
|
||||
TableConfig: jwt.DefaultTableConfig(),
|
||||
})
|
||||
|
||||
// Use with transactions
|
||||
tx, _ := gen.dbConn.BeginTx(context.Background(), nil)
|
||||
tx, _ := sqlDB.Begin()
|
||||
defer tx.Rollback()
|
||||
|
||||
token, _ := gen.ValidateAccess(tx, tokenString)
|
||||
@@ -391,22 +396,35 @@ tx.Commit()
|
||||
|
||||
```go
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"github.com/uptrace/bun"
|
||||
"github.com/uptrace/bun/dialect/pgdialect"
|
||||
"github.com/uptrace/bun/driver/pgdriver"
|
||||
)
|
||||
|
||||
// Get underlying *sql.DB from Bun
|
||||
bunDB := bun.NewDB(sqldb, pgdialect.New())
|
||||
sqlDB := bunDB.DB // Already *sql.DB
|
||||
// Create *sql.DB connection first
|
||||
sqlDB := sql.Open(pgdriver.NewConnector(pgdriver.WithDSN(dsn)))
|
||||
|
||||
// Create generator
|
||||
// Pass sql.DB to both Bun and JWT generator
|
||||
bunDB := bun.NewDB(sqlDB, pgdialect.New())
|
||||
|
||||
// Create generator with the same sql.DB
|
||||
gen, _ := jwt.CreateGenerator(jwt.GeneratorConfig{
|
||||
// ... config
|
||||
DBConn: jwt.NewDBConnection(sqlDB),
|
||||
AccessExpireAfter: 15,
|
||||
RefreshExpireAfter: 1440,
|
||||
FreshExpireAfter: 5,
|
||||
TrustedHost: "example.com",
|
||||
SecretKey: "your-secret-key",
|
||||
DB: sqlDB,
|
||||
DBType: jwt.DatabaseType{
|
||||
Type: jwt.DatabasePostgreSQL,
|
||||
Version: "15",
|
||||
},
|
||||
TableConfig: jwt.DefaultTableConfig(),
|
||||
})
|
||||
|
||||
// Use with transactions
|
||||
tx, _ := gen.dbConn.BeginTx(context.Background(), nil)
|
||||
tx, _ := sqlDB.Begin()
|
||||
defer tx.Rollback()
|
||||
|
||||
token, _ := gen.ValidateAccess(tx, tokenString)
|
||||
@@ -444,7 +462,7 @@ func main() {
|
||||
FreshExpireAfter: 5,
|
||||
TrustedHost: "example.com",
|
||||
SecretKey: "super-secret-key",
|
||||
DBConn: jwt.NewDBConnection(db),
|
||||
DB: db,
|
||||
DBType: jwt.DatabaseType{
|
||||
Type: jwt.DatabasePostgreSQL,
|
||||
Version: "15",
|
||||
@@ -470,7 +488,7 @@ func main() {
|
||||
fmt.Printf("Refresh Token: %s (expires: %d)\n", refreshToken, refreshExp)
|
||||
|
||||
// Validate access token
|
||||
tx, _ := gen.dbConn.BeginTx(context.Background(), nil)
|
||||
tx, _ := db.Begin()
|
||||
defer tx.Rollback()
|
||||
|
||||
token, err := gen.ValidateAccess(tx, accessToken)
|
||||
@@ -489,7 +507,7 @@ func main() {
|
||||
tx.Commit()
|
||||
|
||||
// Try to validate revoked token
|
||||
tx2, _ := gen.dbConn.BeginTx(context.Background(), nil)
|
||||
tx2, _ := db.Begin()
|
||||
defer tx2.Rollback()
|
||||
|
||||
_, err = gen.ValidateAccess(tx2, accessToken)
|
||||
|
||||
Reference in New Issue
Block a user