Documentation
¶
Overview ¶
Package libauth provides secure authentication and authorization services using JWT tokens. It includes functionality for token creation, validation, refresh, password hashing, and permission checks. The package is designed to be extensible with custom permission systems through the AA interface.
Index ¶
- Constants
- Variables
- func CheckAuthorisation[T Authz](ctx context.Context, jwtSecret string, forResource string, permission int) (bool, error)
- func CreateToken[T Authz](cfg CreateTokenArgs, identity string, payload T) (string, time.Time, error)
- func GetClaims[T Authz](ctx context.Context, jwtSecret string) (T, error)
- func GetIdentity[T Authz](ctx context.Context, jwtSecret string) (string, error)
- func RefreshToken[T Authz](cfg CreateTokenArgs, oldToken string) (string, time.Time, error)
- func RefreshTokenWithGracePeriod[T Authz](cfg CreateTokenArgs, oldToken string, gracePeriod time.Duration) (string, bool, time.Time, error)
- type AuthClaims
- type Authz
- type CreateTokenArgs
Constants ¶
const ContextTokenKey = contextKey("jwtToken")
ContextTokenKey is the key used to store the JWT token string in the context. Use context.WithValue(ctx, ContextTokenKey, tokenStr) to inject the token.
Variables ¶
var ( ErrNotAuthorized = errors.New("libauth: not authorized") ErrTokenExpired = errors.New("libauth: token has expired") ErrIssuedAtMissing = errors.New("libauth: issued at claim is missing") ErrIssuedAtInFuture = errors.New("libauth: token is malformed: issued-at time is in the future") ErrIdentityMissing = errors.New("libauth: identity claim is missing") ErrInvalidTokenClaims = errors.New("libauth: invalid token claims") ErrTokenMissing = errors.New("libauth: token is missing") ErrUnexpectedSigningMethod = errors.New("libauth: unexpected signing method") ErrTokenParsingFailed = errors.New("libauth: token parsing failed") ErrTokenSigningFailed = errors.New("libauth: token signing failed") ErrEmptyJWTSecret = errors.New("libauth: JWT secret cannot be empty") ErrEmptyIdentity = errors.New("libauth: identity cannot be empty") )
Common error variables for libauth
Functions ¶
func CheckAuthorisation ¶
func CheckAuthorisation[T Authz](ctx context.Context, jwtSecret string, forResource string, permission int) (bool, error)
CheckAuthorisation verifies that the JWT holds permission for a specific resource and permission. params: - ctx (context.Context) - the context containing the JWT token - jwtSecret (string) - the JWT secret key used to verify the token - forResource (string) - the resource to check permission for - permission (int) - the permission level required returns: (bool, error) - true if the JWT holds permission, false otherwise, and an error if any false, nil -> denied false, err -> validation error
func CreateToken ¶
func CreateToken[T Authz](cfg CreateTokenArgs, identity string, payload T) (string, time.Time, error)
CreateToken creates a new JWT for a given identity and permission payload. params: - cfg (CreateTokenArgs) - the configuration for creating the new token - identity (string) - the identity for which to create the token - payload (T) - the permission payload for the token returns: (string, error) - the new token string and an error if any
Example:
token, err := CreateToken(cfg, "user123", myPermissions)
if err != nil {
// Handle error: check for empty secret or identity.
}
fmt.Println("Generated token:", token)
func GetClaims ¶
GetClaims retrieves the permission claims from the context. params: - ctx (context.Context) - the context containing the JWT token, injected via ContextTokenKey - jwtSecret (string) - the JWT secret key used to verify the token returns: (T, error) - the permission claims and an error if any
func GetIdentity ¶
GetIdentity extracts the identity (subject) from the JWT token stored in the context. params: - ctx (context.Context) - the context containing the JWT token - jwtSecret (string) - the JWT secret key used to verify the token returns: (string, error) - the identity (subject) of the JWT token, and an error if any
func RefreshToken ¶
RefreshToken generates a new JWT from an existing token. params: - cfg (CreateTokenArgs) - the configuration for creating the new token - oldToken (string) - the existing token to refresh returns: (string, error) - the new token string and an error if any Note: RefreshToken only works for non-expired tokens.
func RefreshTokenWithGracePeriod ¶
func RefreshTokenWithGracePeriod[T Authz](cfg CreateTokenArgs, oldToken string, gracePeriod time.Duration) (string, bool, time.Time, error)
RefreshTokenWithGracePeriod refreshes a JWT token only if it's within a given grace period before expiry,
if not, returns the old token.
Types ¶
type AuthClaims ¶
type AuthClaims[T Authz] struct { jwt.RegisteredClaims Identity string `json:"identity"` Permissions T `json:"permissions"` }
AuthClaims defines the JWT claims structure. Generic type T must implement the AA interface (custom permission system) which requires implementations for both authentication and authorization.
func ValidateToken ¶
func ValidateToken[T Authz](ctx context.Context, tokenStr string, jwtSecret string) (*AuthClaims[T], error)
ValidateToken parses and validates a JWT token string. params: - ctx (context.Context) - the context that may hold the JWT token for downstream use - tokenStr (string) - the JWT token string to validate - jwtSecret (string) - the JWT secret to use for validation
Example:
ctx := r.Context()
claims, err := ValidateToken[MyPermissions](ctx, tokenStr, "your-strong-secret")
if err != nil {
// Handle invalid token (expired, malformed, etc.)
}
fmt.Printf("Token is valid for user: %s\n", claims.Identity)
func (AuthClaims[T]) Valid ¶
func (c AuthClaims[T]) Valid() error
Valid implements the jwt.Claims interface, checking the validity of the claims. It validates the expiration, issued-at, and identity claims.
type Authz ¶
type Authz interface {
// RequireAuthorisation checks if the user has the required permission for the resource.
// params:
// - forResource (string) - the resource to check permission for
// - permission (int) - the permission level required
// returns: (bool, error) - true if the user has the required permission, false otherwise, and an error if any
RequireAuthorisation(forResource string, permission int) (bool, error)
}
Authz: authentication and authorization the interface defines methods for permission and authentication checks.
Example usage:
type MyPermissions struct { /* custom permission fields */ }
func (p MyPermissions) RequireAuthorisation(forResource string, permission int) (bool, error) {
// Your permission logic here.
}
func (p MyPermissions) RequireAuthentication(forIdentity string) (bool, error) {
// Your authentication logic here.
}
type CreateTokenArgs ¶
CreateTokenArgs holds the required settings for JWT creation. Example:
cfg := CreateTokenArgs{
JWTSecret: "your-strong-secret",
JWTExpiry: 2 * time.Hour, // token valid for 2 hours
}