Documentation
¶
Index ¶
- Variables
- type Claims
- type JWKSValidator
- type Token
- type TokenInfo
- func (t *TokenInfo) GetArrayMapClaim(key string) []map[string]any
- func (t *TokenInfo) GetBoolClaim(key string) bool
- func (t *TokenInfo) GetClaim(key string) any
- func (t *TokenInfo) GetFloat64Claim(key string) float64
- func (t *TokenInfo) GetIntClaim(key string) int
- func (t *TokenInfo) GetMapClaim(key string) map[string]any
- func (t *TokenInfo) GetOrganizationID() string
- func (t *TokenInfo) GetRawClaims() map[string]any
- func (t *TokenInfo) GetScopes() []string
- func (t *TokenInfo) GetStringClaim(key string) string
- func (t *TokenInfo) GetStringSliceClaim(key string) []string
- func (t *TokenInfo) GetUserID() string
- func (t *TokenInfo) HasAllScopes(scopes ...string) bool
- func (t *TokenInfo) HasAnyScope(scopes ...string) bool
- func (t *TokenInfo) HasAudience(audience string) bool
- func (t *TokenInfo) HasScope(scope string) bool
- func (t *TokenInfo) IsExpired() bool
- type TokenValidator
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidConfig indicates invalid validator configuration. ErrInvalidConfig = errors.New("invalid validator configuration") // ErrTokenExpired indicates the token has expired. ErrTokenExpired = errors.New("token expired") // ErrInvalidIssuer indicates the token issuer doesn't match expected value. ErrInvalidIssuer = errors.New("invalid issuer") // ErrInvalidAudience indicates the token audience doesn't match expected value. ErrInvalidAudience = errors.New("invalid audience") // ErrTokenNotYetValid indicates the token is not yet valid (nbf claim). ErrTokenNotYetValid = errors.New("token not yet valid") // ErrInvalidSignature indicates the token signature verification failed. ErrInvalidSignature = errors.New("invalid signature") // ErrKeyNotFound indicates the public key for the token was not found. ErrKeyNotFound = errors.New("public key not found") // ErrJWKSFetchFailed indicates JWKS fetch from the endpoint failed. ErrJWKSFetchFailed = errors.New("JWKS fetch failed") )
Sentinel errors for use with errors.Is()
Functions ¶
This section is empty.
Types ¶
type Claims ¶
type Claims struct {
// Standard JWT claims (RFC 7519)
Issuer string `json:"iss,omitempty"` // Token issuer (Logto endpoint)
Subject string `json:"sub,omitempty"` // Subject - user ID
Audience []string `json:"aud,omitempty"` // Intended audience (API resource indicator)
ExpiresAt *time.Time `json:"exp,omitempty"` // Expiration time
NotBefore *time.Time `json:"nbf,omitempty"` // Not valid before
IssuedAt *time.Time `json:"iat,omitempty"` // Issued at time
ID string `json:"jti,omitempty"` // Unique token identifier
// Logto-specific claims
ClientID string `json:"client_id,omitempty"` // Application that requested the token
OrganizationID string `json:"organization_id,omitempty"` // Organization context (for org-scoped tokens)
// Permissions (space-separated string from OIDC provider)
Scope string `json:"scope,omitempty"` // Space-separated permissions
}
Claims represents JWT token claims from Logto Identity Provider. This is used internally for parsing JWT tokens. See: https://docs.logto.io/authorization/validate-access-tokens
func (*Claims) HasAudience ¶
HasAudience checks if the token was issued for the specified audience. The audience claim (aud) can be a single string or an array of strings. This is critical for security - tokens should only be accepted if issued for the specific API resource (audience) that is validating them.
func (*Claims) UnmarshalJSON ¶
UnmarshalJSON implements custom JSON unmarshaling to handle: - Unix timestamps for time fields (exp, nbf, iat) - Audience as either string or array of strings
type JWKSValidator ¶
type JWKSValidator struct {
// contains filtered or unexported fields
}
JWKSValidator validates JWT tokens using cached JWKS public keys
func NewJWKSValidator ¶
func NewJWKSValidator(jwksURL, issuer, audience string, cacheTTL time.Duration, logger *slog.Logger) (*JWKSValidator, error)
NewJWKSValidator creates a new JWT validator with JWKS caching.
Parameters:
- jwksURL: URL to fetch JWKS public keys from (e.g., "https://your-tenant.logto.app/oidc/jwks")
- issuer: Expected token issuer (e.g., "https://your-tenant.logto.app/oidc")
- audience: Expected audience - the API resource indicator the token was issued for. This is critical for security: tokens issued for different APIs will be rejected. Use empty string to skip audience validation (NOT recommended for production).
- cacheTTL: How long to cache JWKS keys before refreshing
- logger: Optional slog.Logger for debug output (nil uses slog.Default())
func (*JWKSValidator) StartBackgroundRefresh ¶
func (v *JWKSValidator) StartBackgroundRefresh(ctx context.Context, interval time.Duration)
StartBackgroundRefresh starts a goroutine to refresh JWKS periodically. The ctx parameter controls the lifecycle of the background goroutine - when ctx is cancelled, the background refresh stops. Each refresh operation uses a fresh context with 30s timeout.
func (*JWKSValidator) ValidateToken ¶
ValidateToken validates a JWT token and returns TokenInfo
type Token ¶
type Token interface {
// GetUserID returns the subject (sub) claim - the user identifier
GetUserID() string
// GetOrganizationID returns the organization context (if present)
GetOrganizationID() string
// GetScopes returns parsed scope permissions
GetScopes() []string
// HasScope checks if token has a specific permission
HasScope(scope string) bool
// HasAllScopes checks if token has all specified permissions
HasAllScopes(scopes ...string) bool
// HasAnyScope checks if token has any of the specified permissions
HasAnyScope(scopes ...string) bool
// GetRawClaims returns all JWT claims for custom claim access
GetRawClaims() map[string]any
}
Token represents a validated JWT access token. Implement this interface to create custom token types with typed claims.
Example of creating a custom token type:
type MyToken struct {
*validator.TokenInfo
TenantID string
Roles []string
}
func NewMyToken(info *validator.TokenInfo) *MyToken {
return &MyToken{
TokenInfo: info,
TenantID: info.GetStringClaim("tenant_id"),
Roles: info.GetStringSliceClaim("roles"),
}
}
type TokenInfo ¶
type TokenInfo struct {
// Standard JWT claims (RFC 7519)
Issuer string // iss - token issuer (Logto endpoint)
Subject string // sub - user ID
Audience []string // aud - API resource(s) token was issued for
ExpiresAt *time.Time // exp - token expiration time
IssuedAt *time.Time // iat - when token was issued
NotBefore *time.Time // nbf - token not valid before (nil if not set)
JWTID string // jti - unique token identifier
// Logto-specific claims
ClientID string // client_id - application that requested the token
OrganizationID string // organization_id - organization context (for org-scoped tokens)
Scopes []string // scope - parsed permissions
// Convenience alias (for backward compatibility)
UserID string // Alias for Subject (sub claim)
// RawClaims contains all JWT claims for access to custom claims
// configured via Logto Custom JWT feature.
// See: https://docs.logto.io/developers/custom-token-claims
RawClaims map[string]any
}
TokenInfo represents a validated Logto JWT access token. This is NOT a full user - only security context from the token. Use Client.GetUser() to get full user profile.
Implements the Token interface.
See: https://docs.logto.io/authorization/validate-access-tokens
func (*TokenInfo) GetArrayMapClaim ¶ added in v1.1.4
GetArrayMapClaim returns a custom claim as []map[string]any. Handles JSON arrays of objects which are decoded as []any containing map[string]any items. Returns nil if claim doesn't exist or cannot be converted.
func (*TokenInfo) GetBoolClaim ¶
GetBoolClaim returns a custom claim as bool. Returns false if claim doesn't exist or is not a bool.
func (*TokenInfo) GetClaim ¶
GetClaim returns a custom claim value by key. Returns nil if the claim doesn't exist or RawClaims is nil.
func (*TokenInfo) GetFloat64Claim ¶
GetFloat64Claim returns a custom claim as float64. JSON numbers are decoded as float64. Returns 0 if claim doesn't exist or is not a number.
func (*TokenInfo) GetIntClaim ¶
GetIntClaim returns a custom claim as int. Converts from float64 since JSON numbers are decoded as float64. Returns 0 if claim doesn't exist or is not a number.
func (*TokenInfo) GetMapClaim ¶ added in v1.1.4
GetMapClaim returns a custom claim as map[string]any. JSON objects are decoded as map[string]any. Returns nil if claim doesn't exist or is not a map.
func (*TokenInfo) GetOrganizationID ¶
GetOrganizationID returns the organization context (if present)
func (*TokenInfo) GetRawClaims ¶
GetRawClaims returns all JWT claims for custom claim access
func (*TokenInfo) GetStringClaim ¶
GetStringClaim returns a custom claim as string. Returns empty string if claim doesn't exist or is not a string.
func (*TokenInfo) GetStringSliceClaim ¶
GetStringSliceClaim returns a custom claim as []string. Handles JSON arrays which are decoded as []any. Returns nil if claim doesn't exist or cannot be converted.
func (*TokenInfo) HasAllScopes ¶
HasAllScopes checks if token has all of the specified permissions
func (*TokenInfo) HasAnyScope ¶
HasAnyScope checks if token has any of the specified permissions
func (*TokenInfo) HasAudience ¶
HasAudience checks if token was issued for the specified audience.