This document covers creating and signing JWT tokens using the jwt library.
func New(method SigningMethod, opts ...TokenOption) *TokenCreates a new Token with the specified signing method and an empty MapClaims. Additional options can be specified for future extensibility.
func NewWithClaims(method SigningMethod, claims Claims, opts ...TokenOption) *TokenCreates a new Token with the specified signing method and claims. This is the recommended way to create tokens with custom claims.
Parameters:
method - The signing method to use (e.g., jwt.SigningMethodHS256)claims - Claims to embed in the token (can be RegisteredClaims, MapClaims, or custom)opts - Optional token options (currently unused but reserved for future use)type Token struct {
Raw string
Method SigningMethod
Header map[string]any
Claims Claims
Signature []byte
Valid bool
}Fields:
Raw - The raw token string (populated when parsing)Method - The signing method used or to be usedHeader - The first segment of the token in decoded form (typically contains "typ" and "alg")Claims - The second segment of the token in decoded formSignature - The third segment of the token in decoded form (populated when parsing)Valid - Specifies if the token is valid (populated when parsing/verifying)func (t *Token) SignedString(key any) (string, error)Creates and returns a complete, signed JWT string. The token is signed using the SigningMethod specified in the token. The key type must match the signing method:
[]byte*rsa.PrivateKey*ecdsa.PrivateKeyed25519.PrivateKeyReturns the complete JWT string in format: header.payload.signature
func (t *Token) SigningString() (string, error)Generates the signing string without the signature. This is used internally by SignedString but can be useful for custom signing implementations. Returns the string in format: header.payload
func (*Token) EncodeSegment(seg []byte) stringEncodes a JWT segment using base64url encoding with padding stripped, as required by the JWT specification.
type TokenOption func(*Token)A reserved type for future token creation options. Currently unused but allows for forward compatibility.
import (
"fmt"
"time"
"github.com/golang-jwt/jwt/v5"
)
// Create claims
claims := jwt.MapClaims{
"sub": "user123",
"name": "John Doe",
"iat": time.Now().Unix(),
"exp": time.Now().Add(24 * time.Hour).Unix(),
}
// Create token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
// Sign with secret key
secretKey := []byte("your-256-bit-secret")
tokenString, err := token.SignedString(secretKey)
if err != nil {
panic(err)
}
fmt.Println("Token:", tokenString)import (
"crypto/rsa"
"time"
"github.com/golang-jwt/jwt/v5"
)
// Load RSA private key (example - in practice load from file)
var privateKey *rsa.PrivateKey
// Create registered claims
claims := jwt.RegisteredClaims{
Issuer: "my-service",
Subject: "user456",
Audience: jwt.ClaimStrings{"client-app"},
ExpiresAt: jwt.NewNumericDate(time.Now().Add(1 * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: "token-id-123",
}
// Create and sign token
token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
tokenString, err := token.SignedString(privateKey)
if err != nil {
panic(err)
}import (
"time"
"github.com/golang-jwt/jwt/v5"
)
// Define custom claims
type CustomClaims struct {
Username string `json:"username"`
Roles []string `json:"roles"`
jwt.RegisteredClaims
}
// Create custom claims
claims := CustomClaims{
Username: "johndoe",
Roles: []string{"admin", "user"},
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(2 * time.Hour)),
IssuedAt: jwt.NewNumericDate(time.Now()),
},
}
// Create and sign token
token := jwt.NewWithClaims(jwt.SigningMethodHS512, claims)
secretKey := []byte("your-secret-key")
tokenString, err := token.SignedString(secretKey)import (
"crypto/ecdsa"
"time"
"github.com/golang-jwt/jwt/v5"
)
// Load ECDSA private key
var ecPrivateKey *ecdsa.PrivateKey
// Create claims
claims := jwt.RegisteredClaims{
Subject: "user789",
ExpiresAt: jwt.NewNumericDate(time.Now().Add(30 * time.Minute)),
}
// Create and sign token with ES256
token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
tokenString, err := token.SignedString(ecPrivateKey)import (
"github.com/golang-jwt/jwt/v5"
)
// Create token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": "user123",
})
// Add custom header fields
token.Header["kid"] = "key-id-1" // Key ID
token.Header["cty"] = "JWT" // Content Type
// Sign token
secretKey := []byte("secret")
tokenString, err := token.SignedString(secretKey)exp) to limit token validityiat (issued at) claim for token age verificationaud) to prevent token reuse across servicesAlways check for errors when signing tokens:
tokenString, err := token.SignedString(key)
if err != nil {
// Handle errors appropriately
// Common errors: invalid key type, signing failure
return fmt.Errorf("failed to sign token: %w", err)
}