gojwt

package module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 15, 2023 License: MIT Imports: 12 Imported by: 0

README

GoJWT - JSON Web Tokens in Go

GoReportCard GoDoc GitHub Workflow Status CodeFactor License

GoJWT is a simple and lightweight library for creating, formatting, manipulating, signing and validating JSON Web Tokens in Golang, used for token-based authorization. As specified in RFC 7519, this library provides standard encryption algorithms and claim checks.

Installation

go get -u github.com/tobyguelly/gojwt

Supported Algorithms

HS256, HS384, HS512, RS256, RS384, RS512

Examples

Creating JWTs
  • You can create JWTs using the NewJWT function
  • Then you can format and sign them into a JWT using the SignParse() method
jwt := gojwt.NewJWT()
jwt.Payload.SetCustom("username", "admin")
token, err := jwt.SignParse("mysecret")
if err != nil {
    fmt.Println(token)
}
  • Alternatively you can use JWT builders to create tokens more easily
token, err := gojwt.WithBuilder().Custom("username", "admin").ExpiresIn(time.Second * 10).Sign("mysecret")
if err == nil {
    fmt.Println(token)
}
Custom Fields in the Token Payload
  • Custom fields can be applied to the JWT Payload by setting the Custom property to a map
jwt.Payload.Custom = gojwt.Map{
	"string": "Example String",
	"number": 1234,
}
Signing and Validating Tokens
  • JWTs can be signed and validated with a secret string with the Sign() and Validate() method
  • Dependent of the Algorithm field in the JWT Header, a symmetric encryption algorithm will be chosen
  • The error returned by the Validate() method indicates, whether the validation was successful or not
    • If the token is valid using the given secret, nil is returned
    • If the token has not been signed yet, the error ErrTokNotSig is returned
    • If an invalid secret was passed, the error ErrInvSecKey is returned
    • If the signature algorithm given in the JWT Header is not supported, the error ErrAlgNotImp is returned
    • If the token has expired or is not valid yet based on the ExpirationTime and NotBefore claims, ErrInvTokPer is returned
err := jwt.Sign("mysecret")
if err == nil {
	fmt.Println("JWT successfully signed!")
}
err := jwt.Validate("mysecret")
if err == nil {
	fmt.Println("JWT successfully validated!")
}
Support for Asymmetric Encryption/Decryption
  • JWTs can also be signed using public/private keys and asymmetric encryption by using the SignWithKey() and ValidateWithKey() method
  • Dependent of the Algorithm field in the JWT Header, an asymmetric encryption/decryption algorithm will be chosen
  • The same type of errors as for the symmetric encryption are returned by those methods
privateKey, _ := rsa.GenerateKey(rand.Reader, 2048)
publicKey := privateKey.PublicKey

err := jwt.SignWithKey("", publicKey)
if err == nil {
	fmt.Println("JWT successfully signed using public key!")
}
err := jwt.ValidateWithKey("", *privateKey)
if err == nil {
	fmt.Println("JWT successfully validated using private key!")
}
Loading Tokens
  • Parsed JWTs can be loaded by using the LoadJWT function
    • If the given string is not a valid JWT, an error is returned
jwt, err := gojwt.LoadJWT("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnb2p3dCIsInN1YiI6IkV4YW1wbGUgVG9rZW4ifQ.5UDIu1WUy20KEM_vGUBdYnOBDiwfA94_vYvE3cehGS8")
if err == nil {
	fmt.Println("JWT successfully loaded!")
}
Token Timeouts
  • Tokens can have an expiration and a starting timestamp which is set using the NotBefore and ExpirationTime properties in the payload
  • Then the validation process automatically returns ErrInvTokPer if the timestamp in the NotBefore field has not passed yet or the ExpirationTime has passed
    • This error can be ignored, it is informational only
  • If these properties are not set, tokens are valid from the second they are signed on and do not expire
jwt.Payload.NotBefore = gojwt.Now().Add(time.Second * 5)
jwt.Payload.ExpirationTime = gojwt.Wrap(time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC))

Documentation

Index

Constants

View Source
const (
	// AlgHS256 indicates that the JWT uses the HS256 algorithm for signing the signature.
	AlgHS256 = "HS256"

	// AlgHS384 indicates that the JWT uses the HS256 algorithm for signing the signature.
	AlgHS384 = "HS384"

	// AlgHS512 indicates that the JWT uses the HS512 algorithm for signing the signature.
	AlgHS512 = "HS512"

	// AlgRS256 indicates that the JWT uses the RS256 algorithm for encrypting and decrypting the signature.
	AlgRS256 = "RS256"

	// AlgRS384 indicates that the JWT uses the RS384 algorithm for encrypting and decrypting the signature.
	AlgRS384 = "RS384"

	// AlgRS512 indicates that the JWT uses the RS512 algorithm for encrypting and decrypting the signature.
	AlgRS512 = "RS512"
)
View Source
const (
	// TypJWT indicates that the token type is JWT.
	TypJWT = "JWT"
)

Variables

View Source
var (
	// ErrAlgNotImp indicates that the algorithm in the JWT header is not implemented for the signing/validating method.
	ErrAlgNotImp = errors.New("SIGNATURE ALGORITHM NOT IMPLEMENTED FOR METHOD")

	// ErrTokNotSig indicates that the JWT has not been signed yet, and therefore can't be validated.
	ErrTokNotSig = errors.New("TOKEN NOT SIGNED / MISSING SIGNATURE")

	// ErrInvSecKey indicates that the JWT has failed a validation, because of an invalid secret key.
	ErrInvSecKey = errors.New("INVALID SECRET")

	// ErrBadJWTTok indicates that a given string is not a valid JWT token.
	ErrBadJWTTok = errors.New("NOT A JWT / BAD JWT")

	// ErrInvTokPrd indicates that a given JWT has failed a validation.
	// This happened because of either the nbf (NotBefore) or exp (ExpirationTime) claim had invalid dates.
	ErrInvTokPrd = errors.New("TOKEN VALIDITY PERIOD EXPIRED OR NOT STARTED")

	// ErrPayFieldVal indicates that a given payload has failed field format validation.
	ErrPayFieldVal = errors.New("ONE OR MORE FIELDS PRODUCE A VALIDATION ERROR")
)
View Source
var (
	// DefaultHeader is the default header for JWT tokens using the HS256 algorithm.
	DefaultHeader = Header{
		Algorithm: AlgHS256,
		Type:      TypJWT,
	}
	// DefaultFieldLength is the default maximum length of payload fields.
	DefaultFieldLength = 255 // TODO
)
View Source
var (
	Algorithms = AlgorithmMap{
		AlgHS256: SignHS256,
		AlgHS384: SignHS384,
		AlgHS512: SignHS512,
	}
	EncryptionAlgorithms = EncryptionAlgorithmMap{
		AlgRS256: EncryptRS256,
		AlgRS384: EncryptRS384,
		AlgRS512: EncryptRS512,
	}
	DecryptionAlgorithms = DecryptionAlgorithmMap{
		AlgRS256: DecryptRS256,
		AlgRS384: DecryptRS384,
		AlgRS512: DecryptRS512,
	}
)

Functions

func DecodeBase64

func DecodeBase64(message string) ([]byte, error)

DecodeBase64 decodes a string with the base64 algorithm.

func DecryptRS256 added in v1.1.0

func DecryptRS256(encodedCipher string, label []byte, privateKey rsa.PrivateKey) (string, error)

DecryptRS256 decrypts a base64 rawUrlEncoded cipher string with a secret string and an RSA private key using the RS256 algorithm.

func DecryptRS384 added in v1.1.0

func DecryptRS384(encodedCipher string, label []byte, privateKey rsa.PrivateKey) (string, error)

DecryptRS384 decrypts a base64 rawUrlEncoded cipher string with a secret string and an RSA private key using the RS384 algorithm.

func DecryptRS512 added in v1.1.0

func DecryptRS512(encodedCipher string, label []byte, privateKey rsa.PrivateKey) (string, error)

DecryptRS512 decrypts a base64 rawUrlEncoded cipher string with a secret string and an RSA private key using the RS512 algorithm.

func EncodeBase64

func EncodeBase64(message string) string

EncodeBase64 encodes a string with the base64 algorithm.

func EncryptRS256 added in v1.1.0

func EncryptRS256(message string, label []byte, publicKey rsa.PublicKey) (string, error)

EncryptRS256 signs a message string with a secret string and an RSA public key using the RS256 algorithm with additional base64 rawURLEncoding of the result cipher.

func EncryptRS384 added in v1.1.0

func EncryptRS384(message string, label []byte, publicKey rsa.PublicKey) (string, error)

EncryptRS384 signs a message string with a secret string and an RSA public key using the RS384 algorithm with additional base64 rawURLEncoding of the result cipher.

func EncryptRS512 added in v1.1.0

func EncryptRS512(message string, label []byte, publicKey rsa.PublicKey) (string, error)

EncryptRS512 signs a message string with a secret string and an RSA public key using the RS512 algorithm with additional base64 rawURLEncoding of the result cipher.

func SignHS256

func SignHS256(message, secret string) (string, error)

SignHS256 signs a message string with a secret string using the HS256 algorithm with additional base64 rawURLEncoding of the result hash.

func SignHS384 added in v1.1.0

func SignHS384(message, secret string) (string, error)

SignHS384 signs a message string with a secret string using the HS384 algorithm with additional base64 rawURLEncoding of the result hash.

func SignHS512 added in v1.1.0

func SignHS512(message, secret string) (string, error)

SignHS512 signs a message string with a secret string using the HS512 algorithm with additional base64 rawURLEncoding of the result hash.

Types

type AlgorithmMap added in v1.3.0

type AlgorithmMap map[string]func(message, secret string) (string, error)

type Builder added in v1.2.0

type Builder struct {
	JWT
}

Builder aims to wrap a JWT value to provide setters and chaining options for properties.

func WithBuilder added in v1.2.0

func WithBuilder() *Builder

WithBuilder creates a new Builder with an empty JWT token.

func (*Builder) Audience added in v1.2.0

func (this *Builder) Audience(aud string) *Builder

Audience sets the audience property of the JWT.

func (*Builder) Custom added in v1.2.0

func (this *Builder) Custom(key string, value interface{}) *Builder

Custom sets a custom property in the JWT.

func (*Builder) ExpirationTime added in v1.2.0

func (this *Builder) ExpirationTime(exp time.Time) *Builder

ExpirationTime sets the expiration time property of the JWT.

func (*Builder) ExpiresIn added in v1.2.0

func (this *Builder) ExpiresIn(duration time.Duration) *Builder

ExpiresIn sets the expiration time property of the JWT to the current time and adds a specified time.Duration value to it.

func (*Builder) IssuedAt added in v1.2.0

func (this *Builder) IssuedAt(iat time.Time) *Builder

IssuedAt sets the issued at property of the JWT.

func (*Builder) IssuedNow added in v1.2.0

func (this *Builder) IssuedNow() *Builder

IssuedNow sets the issued at property of the JWT to the current timestamp.

func (*Builder) Issuer added in v1.2.0

func (this *Builder) Issuer(iss string) *Builder

Issuer sets the issuer property of the JWT.

func (*Builder) JWTID added in v1.2.0

func (this *Builder) JWTID(jti string) *Builder

JWTID sets the JWTID property of the JWT.

func (*Builder) NotBefore added in v1.2.0

func (this *Builder) NotBefore(nbf time.Time) *Builder

NotBefore sets the not before property of the JWT.

func (*Builder) Sign added in v1.2.0

func (this *Builder) Sign(secret string) (string, error)

Sign signs the JWT with a given secret and returns the signed JWT as a string or a possible error.

func (*Builder) SignWithKey added in v1.2.0

func (this *Builder) SignWithKey(label string, key rsa.PublicKey) (string, error)

SignWithKey signs the JWT with a given label and rsa.PublicKey and returns the signed JWT as a string or a possible error.

func (*Builder) Subject added in v1.2.0

func (this *Builder) Subject(sub string) *Builder

Subject sets the subject property of the JWT.

type DecryptionAlgorithmMap added in v1.3.0

type DecryptionAlgorithmMap map[string]func(message string, label []byte, key rsa.PrivateKey) (string, error)

type EncryptionAlgorithmMap added in v1.3.0

type EncryptionAlgorithmMap map[string]func(message string, label []byte, key rsa.PublicKey) (string, error)
type Header struct {

	// Algorithm is a string containing the identification of the algorithm used for signing a JWT.
	Algorithm string `json:"alg"`

	// ContentType indicates the content type of the token, not required.
	ContentType string `json:"cty,omitempty"`

	// Type indicates the type of the token, must be "JWT" for JWT tokens.
	Type string `json:"typ"`
}

Header is the header section of the JWT token.

func (*Header) IsEmpty

func (this *Header) IsEmpty() bool

IsEmpty returns a bool, whether the Header is empty or not.

func (*Header) Json

func (this *Header) Json() (string, error)

Json formats the Header into JSON format.

type JWT

type JWT struct {

	// Header is the JWT header field.
	Header Header

	// Payload is the JWT payload field.
	Payload Payload

	// Signature is a string holding the JWT Header and the JWT Payload encrypted with the algorithm of the JWT Header.
	// Signature = Header.Algorithm(Header.Json() + "." + Payload.Json(), SECRET)
	Signature string
}

JWT is a struct holding the values a JWT.

func LoadJWT added in v1.2.0

func LoadJWT(token string) (jwt *JWT, err error)

LoadJWT creates a JWT object from a JWT string. Returns empty JWT, ErrBadJWTTok if the JWT is not a valid JWT, or returns the JWT if everything was successful.

func NewJWT

func NewJWT() JWT

NewJWT creates a completely new JWT object with default values.

func (*JWT) Data

func (this *JWT) Data() (data string, err error)

Data formats the Header and Payload fields of a JWT into a string. Result = Base64Encode(Header.Json()) + "." + Base64Encode(Payload.Json())

func (*JWT) GoString added in v1.2.0

func (this *JWT) GoString() (token string)

GoString is the implementation for the GoStringer interface and an alias for String

func (*JWT) IsEmpty

func (this *JWT) IsEmpty() (empty bool)

IsEmpty returns a bool, whether the Header and the Payload are empty or not.

func (*JWT) IsExpired added in v1.2.0

func (this *JWT) IsExpired() (expired bool)

IsExpired returns a bool, whether the token has already expired or is not valid yet.

func (*JWT) IsSigned added in v1.2.0

func (this *JWT) IsSigned() (signed bool)

IsSigned returns a bool, whether the token has been signed already or not.

func (*JWT) Parse added in v1.2.0

func (this *JWT) Parse() (token string, err error)

Parse formats the JWT into a JWT string and returns the result. It requires the token to be signed and the payload and header to be parsed successfully, otherwise it returns ErrTokNotSig. Result = Base64Encode(Header.Json()) + "." + Base64Encode(Payload.Json()) + "." + Signature

func (*JWT) Sign

func (this *JWT) Sign(secret string) (err error)

Sign signs a JWT using a symmetric encryption algorithm and creates the Signature, saved in the JWT. This method overwrites the Signature field in the JWT if it exists. Returns ErrAlgNotImp if the algorithm in the Header is not implemented yet or an asymmetric encryption algorithm. or returns ErrInvTokPrd if the token period has expired before signing.

func (*JWT) SignParse added in v1.3.0

func (this *JWT) SignParse(secret string) (token string, err error)

SignParse performs the Sign and Parse operations in one single step.

func (*JWT) SignParseWithKey added in v1.3.0

func (this *JWT) SignParseWithKey(label string, key rsa.PublicKey) (token string, err error)

SignParseWithKey performs the SignWithKey and Parse operations in one single step.

func (*JWT) SignWithKey added in v1.1.0

func (this *JWT) SignWithKey(label string, key rsa.PublicKey) (err error)

SignWithKey signs a JWT using an asymmetric encryption algorithm and creates the Signature, saved in the JWT. This method overwrites the Signature field in the JWT if it exists. Returns ErrAlgNotImp if the algorithm in the Header is not implemented yet or a symmetric encryption algorithm or returns ErrInvTokPrd if the token period has expired before signing.

func (*JWT) String

func (this *JWT) String() (token string)

String formats the JWT into a JWT string and ignores probable errors. To parse tokens in production environments, it is recommended to use the Parse method.

func (*JWT) Validate

func (this *JWT) Validate(secret string) (err error)

Validate validates a JWT based on a given secret string using a symmetric encryption algorithm. Returns ErrAlgNotImp if the algorithm in the Header is not implemented yet, ErrTokNotSig if the token has not been signed yet, ErrInvTokPrd if the token period has expired and ErrInvSecKey if the entered secret string is invalid corresponding to the signature. Returns nil if the JWT is validated with the entered secret.

func (*JWT) ValidateWithKey added in v1.1.0

func (this *JWT) ValidateWithKey(label string, key rsa.PrivateKey) (err error)

ValidateWithKey validates a JWT based on a given secret string using an asymmetric encryption algorithm Returns ErrAlgNotImp if the algorithm in the Header is not implemented yet, ErrTokNotSig if the token has not been signed yet, ErrInvTokPrd if the token period has expired and ErrInvSecKey if the entered key and/or label is invalid corresponding to the signature. Returns nil if the JWT is validated with the entered key.

type Map added in v1.2.0

type Map map[string]interface{}

type Payload

type Payload struct {

	// Issuer is the issuer claim in the JWT token.
	Issuer string `json:"iss,omitempty"`

	// Subject is the subject claim in the JWT token.
	Subject string `json:"sub,omitempty"`

	// Audience is the audience claim in the JWT token.
	Audience string `json:"aud,omitempty"`

	// ExpirationTime is the expiration time claim in the JWT token.
	ExpirationTime *Time `json:"exp,omitempty"`

	// NotBefore is the not before claim in the JWT token.
	NotBefore *Time `json:"nbf,omitempty"`

	// IssuedAt is the issued at claim in the JWT token.
	IssuedAt *Time `json:"iat,omitempty"`

	// JWTID is the JWT id claim in the JWT token.
	JWTID string `json:"jti,omitempty"`

	// Custom is a map containing custom keys and claims for the JWT token.
	Custom Map `json:"-"`
}

Payload is the payload section of the JWT token.

func (*Payload) GetCustom

func (this *Payload) GetCustom(key string) interface{}

GetCustom returns a field in the Map values, identified by the key.

func (*Payload) IsEmpty

func (this *Payload) IsEmpty() bool

IsEmpty returns a bool, whether the Payload is empty or not.

func (*Payload) Json

func (this *Payload) Json() (string, error)

Json formats the Payload into JSON format.

func (*Payload) SetCustom

func (this *Payload) SetCustom(key string, value interface{}) *Payload

SetCustom sets a key and a value in the Map values.

type Time added in v1.2.0

type Time struct {
	time.Time
}

Time is a struct wrapping a time.Time value from the standard library. It implements the json.Marshaler and json.Unmarshaler interface, and the encoding.TextMarshaler and encoding.TextUnmarshaler interface to override the marshalling to create UNIX timestamps like specified in the JWT standard.

func Now added in v1.2.0

func Now() *Time

Now wraps the current standard library time.Time value.

func Unix added in v1.2.0

func Unix(seconds int64) *Time

Unix loads a timestamp from UNIX seconds.

func Wrap added in v1.2.0

func Wrap(time time.Time) *Time

Wrap wraps a standard library time.Time value.

func (*Time) Add added in v1.2.0

func (this *Time) Add(duration time.Duration) *Time

Add adds a time.Duration to a Time.

func (*Time) MarshalJSON added in v1.2.0

func (this *Time) MarshalJSON() ([]byte, error)

MarshalJSON is the implementation of the json.Marshaler interface. It parses the Time value into a UNIX-Timestamp.

func (*Time) MarshalText added in v1.2.0

func (this *Time) MarshalText() ([]byte, error)

MarshalText is the implementation of the encoding.TextMarshaler interface. It parses the Time value into a UNIX-Timestamp.

func (*Time) UnmarshalJSON added in v1.2.0

func (this *Time) UnmarshalJSON(data []byte) error

UnmarshalJSON is the implementation of the json.Unmarshaler interface. It parses an UNIX-Timestamp into a Time value.

func (*Time) UnmarshalText added in v1.2.0

func (this *Time) UnmarshalText(data []byte) error

UnmarshalText is the implementation of the encoding.TextUnmarshaler interface. It parses an UNIX-Timestamp into a Time value.

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL