go-jwt - Documentation

July 13, 2026 · View on GitHub

Back to README

Prerequisites

  • Go 1.24 or higher
  • Redis server

Installation

Using go get

go get github.com/pardnchiu/go-jwt

From Source

git clone https://github.com/pardnchiu/go-jwt.git
cd go-jwt
go build ./...

Configuration

Config Structure

FieldTypeRequiredDescription
RedisRedisYesRedis connection settings
File*FileNoPEM key file paths
Option*OptionNoToken parameter tuning
Cookie*CookieNoCookie attribute settings
CheckAuthfunc(Auth) (bool, error)NoCustom user validation callback

Redis Settings

FieldTypeRequiredDescription
HoststringYesRedis host address
PortintYesRedis port
PasswordstringNoRedis password
DBintYesRedis database number

Option Defaults

FieldDefaultDescription
AccessTokenExpires15mAccess Token expiration
RefreshIdExpires7dRefresh ID expiration
AccessTokenCookieKeyaccess_tokenAccess Token cookie key
RefreshIdCookieKeyrefresh_idRefresh ID cookie key
MaxVersion5Refresh count before Refresh ID rebuild
RefreshTTL0.5TTL ratio threshold for Refresh ID rebuild
FieldTypeDefaultDescription
Domain*stringNoneCookie domain
Path*string/Cookie path
SameSite*http.SameSiteLaxSameSite attribute
Secure*boolfalseHTTPS only
HttpOnly*booltrueHttpOnly flag

PEM Keys

Three configuration methods are supported, in priority order:

  1. File.PrivateKeyPath / File.PublicKeyPath — specify file paths
  2. Option.PrivateKey / Option.PublicKey — provide PEM text directly
  3. Auto-detect ./keys/private-key.pem and ./keys/public-key.pem; generates a new ECDSA P-256 key pair if not found

Usage

Basic

package main

import (
	"log"
	"net/http"

	"github.com/pardnchiu/go-jwt/core"
)

func main() {
	jwtAuth, err := goJwt.New(goJwt.Config{
		Redis: goJwt.Redis{
			Host: "localhost",
			Port: 6379,
			DB:   0,
		},
	})
	if err != nil {
		log.Fatalf("init failed: %v", err)
	}
	defer jwtAuth.Close()

	http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
		result := jwtAuth.Create(w, r, &goJwt.Auth{
			ID:    "user-1",
			Name:  "Alice",
			Email: "alice@example.com",
			Role:  "admin",
		})
		if !result.Success {
			http.Error(w, result.Error, result.StatusCode)
			return
		}
		w.WriteHeader(result.StatusCode)
	})

	log.Fatal(http.ListenAndServe(":8080", nil))
}

Advanced

package main

import (
	"log"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/pardnchiu/go-jwt/core"
)

func main() {
	secure := true
	jwtAuth, err := goJwt.New(goJwt.Config{
		Redis: goJwt.Redis{
			Host:     "localhost",
			Port:     6379,
			Password: "secret",
			DB:       1,
		},
		Option: &goJwt.Option{
			AccessTokenExpires: 10 * time.Minute,
			RefreshIdExpires:   14 * 24 * time.Hour,
			MaxVersion:         3,
			RefreshTTL:         0.4,
		},
		Cookie: &goJwt.Cookie{
			Secure: &secure,
		},
		CheckAuth: func(auth goJwt.Auth) (bool, error) {
			// return false when the user no longer exists
			return auth.ID != "", nil
		},
	})
	if err != nil {
		log.Fatalf("init failed: %v", err)
	}
	defer jwtAuth.Close()

	r := gin.Default()
	r.POST("/login", func(c *gin.Context) {
		result := jwtAuth.Create(c.Writer, c.Request, &goJwt.Auth{
			ID:    "user-1",
			Name:  "Alice",
			Email: "alice@example.com",
			Scope: []string{"read", "write"},
		})
		if !result.Success {
			c.JSON(result.StatusCode, gin.H{"error": result.Error})
			return
		}
		c.JSON(result.StatusCode, gin.H{
			"token":      result.Token.Token,
			"refresh_id": result.Token.RefreshId,
		})
	})

	auth := r.Group("/")
	auth.Use(jwtAuth.GinMiddleware())
	auth.GET("/me", func(c *gin.Context) {
		user, ok := goJwt.GetAuthDataFromGinContext(c)
		if !ok {
			c.JSON(http.StatusUnauthorized, gin.H{"error": "unauthorized"})
			return
		}
		c.JSON(http.StatusOK, user)
	})
	auth.POST("/logout", func(c *gin.Context) {
		result := jwtAuth.Revoke(c.Writer, c.Request)
		c.JSON(result.StatusCode, gin.H{"success": result.Success, "error": result.Error})
	})

	log.Fatal(r.Run(":8080"))
}

API Reference

New

func New(c Config) (*JWTAuth, error)

Creates a JWTAuth instance, connects Redis, and loads or generates ECDSA keys.

Close

func (j *JWTAuth) Close() error

Closes the Redis connection.

Create

func (j *JWTAuth) Create(w http.ResponseWriter, r *http.Request, auth *Auth) JWTAuthResult

Issues Access Token and Refresh ID, sets cookies, and stores refresh state plus JTI in Redis.

Verify

func (j *JWTAuth) Verify(w http.ResponseWriter, r *http.Request) JWTAuthResult

Verifies the Access Token, checks revocation and device fingerprint, and refreshes transparently when expired.

Revoke

func (j *JWTAuth) Revoke(w http.ResponseWriter, r *http.Request) JWTAuthResult

Revokes the current session: clears cookies, shortens Refresh ID TTL, and marks the Access Token as revoked.

GinMiddleware

func (j *JWTAuth) GinMiddleware() gin.HandlerFunc

Gin middleware that runs Verify and stores *Auth under the user context key.

HTTPMiddleware

func (j *JWTAuth) HTTPMiddleware(next http.Handler) http.Handler

Standard library middleware that runs Verify and stores *Auth in request.Context.

GetAuthDataFromGinContext

func GetAuthDataFromGinContext(c *gin.Context) (*Auth, bool)

Reads authenticated user data from a Gin context.

GetAuthDataFromHTTPRequest

func GetAuthDataFromHTTPRequest(r *http.Request) (*Auth, bool)

Reads authenticated user data from an http.Request context.

Auth

FieldTypeDescription
IDstringUser ID
NamestringDisplay name
EmailstringEmail
ThumbnailstringAvatar URL
Scope[]stringPermission scopes
RolestringRole
LevelintLevel

JWTAuthResult

FieldTypeDescription
StatusCodeintHTTP status code
SuccessboolWhether the operation succeeded
Data*AuthAuthenticated user data
Token*TokenResultIssued token pair
ErrorstringError message
ErrorTagstringMachine-readable error tag

Headers

HeaderDirectionDescription
Authorization: Bearer <token>RequestAccess Token (cookie alternative)
X-Refresh-IDRequestRefresh ID (cookie alternative)
X-Device-FPRequestOverride device fingerprint
X-Device-IDRequestStable device ID
X-New-Access-TokenResponseNew Access Token after refresh
X-New-Refresh-IDResponseNew Refresh ID after full rebuild

©️ 2025 邱敬幃 Pardn Chiu