jwt

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 8, 2023 License: MIT Imports: 18 Imported by: 4

Documentation

Overview

Package jwt handles JSON Web Token defined in RFC 7519.

Index

Examples

Constants

This section is empty.

Variables

View Source
var UnsecureAnyAlgorithm = unsecureAnyAlgorithmVerifier{}

UnsecureAnyAlgorithm is an AlgorithmVerifier that accepts any algorithm.

View Source
var UnsecureAnyAudience = unsecureAnyAudienceVerifier{}
View Source
var UnsecureAnyIssuerSubject = unsecureAnyIssuerSubjectVerifier{}

UnsecureAnyIssuerSubject is an IssuerSubjectVerifier that accepts any issuer and subject. This is not recommended.

Functions

func Sign

func Sign(header *jws.Header, claims *Claims, key sig.SigningKey) ([]byte, error)
Example
package main

import (
	"fmt"
	"log"

	"github.com/shogo82148/goat/jwa"
	_ "github.com/shogo82148/goat/jwa/eddsa"
	"github.com/shogo82148/goat/jwk"
	"github.com/shogo82148/goat/jws"
	"github.com/shogo82148/goat/jwt"
)

func main() {
	// prepare signing key.
	raw := `{"crv":"Ed25519","d":"AEJRVb3JLIx7nYP3YGbdiEcmfiQs8ZO89Fpg4Iw7CX4",
		"kty":"OKP","x":"BFfXRkBCOZGnrRClfKmI3fH_fgnvG_HF71tPkHHtdFw"}`
	key, err := jwk.ParseKey([]byte(raw))
	if err != nil {
		log.Fatal(err)
	}
	signingKey := jwa.EdDSA.New().NewSigningKey(key)

	// prepare the header and the claims.
	header := jws.NewHeader()
	header.SetAlgorithm(jwa.EdDSA)
	claims := new(jwt.Claims)
	claims.Issuer = "https://github.com/shogo82148/goat"
	claims.Audience = []string{"https://github.com/shogo82148"}

	// sign
	token, err := jwt.Sign(header, claims, signingKey)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(string(token))

}
Output:

eyJhbGciOiJFZERTQSJ9.eyJhdWQiOiJodHRwczovL2dpdGh1Yi5jb20vc2hvZ284MjE0OCIsImlzcyI6Imh0dHBzOi8vZ2l0aHViLmNvbS9zaG9nbzgyMTQ4L2dvYXQifQ.2p0nndDnxqsA9u1unq2bLPJiJpSj0hOfCNXe1b_Dsu7LskZPj1lFxv56rptqalzYVmR8kcrMyEIrRb94gr_KBw

Types

type AlgorithmVerifier added in v0.1.0

type AlgorithmVerifier interface {
	VerifyAlgorithm(ctx context.Context, alg jwa.SignatureAlgorithm) error
}

AlgorithmVerifier verifies the algorithm used for signing.

type AllowedAlgorithms added in v0.1.0

type AllowedAlgorithms []jwa.SignatureAlgorithm

AllowedAlgorithms is an AlgorithmVerifier that accepts only the specified algorithms.

func (AllowedAlgorithms) VerifyAlgorithm added in v0.1.0

func (a AllowedAlgorithms) VerifyAlgorithm(ctx context.Context, alg jwa.SignatureAlgorithm) error

type Audience added in v0.1.0

type Audience string

func (Audience) VerifyAudience added in v0.1.0

func (a Audience) VerifyAudience(ctx context.Context, aud []string) error

type AudienceVerifier added in v0.1.0

type AudienceVerifier interface {
	VerifyAudience(ctx context.Context, aud []string) error
}

AudienceVerifier verifies the audience.

type Claims

type Claims struct {
	// RFC 7519 Section 4.1.1. "iss" (Issuer) Claim
	Issuer string

	// RFC 7519 Section 4.1.2. "sub" (Subject) Claim
	Subject string

	// RFC 7519 Section 4.1.3. "aud" (Audience) Claim
	Audience []string

	// RFC 7519 Section 4.1.4. "exp" (Expiration Time) Claim
	ExpirationTime time.Time

	// RFC 7519 Section 4.1.5. "nbf" (Not Before) Claim
	NotBefore time.Time

	// RFC 7519 Section 4.1.6. "iat" (Issued At) Claim
	IssuedAt time.Time

	// RFC 7519 Section 4.1.7. "jti" (JWT ID) Claim
	JWTID string

	// Raw is the raw data of JSON-decoded JOSE header.
	// JSON numbers are decoded as json.Number to avoid data loss.
	Raw map[string]any
}

Claims is a JWT Claims Set defined in RFC 7519.

func (*Claims) DecodeCustom

func (c *Claims) DecodeCustom(v any) error

DecodeCustom decodes custom claims into v. v must be a pointer.

Example
package main

import (
	"encoding/json"
	"fmt"
	"log"
	"math/big"
	"time"

	_ "github.com/shogo82148/goat/jwa/eddsa"
	"github.com/shogo82148/goat/jwt"
)

func main() {
	claims := new(jwt.Claims)
	claims.Raw = map[string]any{
		"string": "it is custom claim",
		"bytes":  "YmFzZTY0LXJhd3VybCBlbmNvZGVkIGJ5dGUgc2VxdWVuY2U",
		"time":   json.Number("1234567890"),
		"bigint": "nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A",
	}

	var myClaims struct {
		String string    `jwt:"string"`
		Bytes  []byte    `jwt:"bytes"`
		Time   time.Time `jwt:"time"`
		BigInt *big.Int  `jwt:"bigint"`
	}
	if err := claims.DecodeCustom(&myClaims); err != nil {
		log.Fatal(err)
	}

	fmt.Println(myClaims.String)
	fmt.Println(string(myClaims.Bytes))
	fmt.Println(myClaims.Time)
	fmt.Println(myClaims.BigInt)
}
Output:

it is custom claim
base64-rawurl encoded byte sequence
2009-02-13 23:31:30 +0000 UTC
71185727259945196030657158393116523760833600269775786460544228200423405551456

func (*Claims) EncodeCustom

func (c *Claims) EncodeCustom(v any) error

EncodeCustom encodes custom claims from v.

EncodeCustom works like encoding/json.Marshal, with a few differences. Due to the different value conversion rules, the "jwt" key is used for structure field tags instead of the "json" key.

The following conversions are made to match the general encoding of JWT claims:

  • []byte is converted to base64 raw-url encoded string
  • big.Int is converted to big-endian base64 raw-url encoded string
  • *time.Time is converted to number in seconds from unix time epoch

The tag must always be specified to avoid accidentally exposing the field. Claim names are case sensitive.

Example
package main

import (
	"fmt"
	"log"
	"math/big"
	"time"

	_ "github.com/shogo82148/goat/jwa/eddsa"
	"github.com/shogo82148/goat/jwt"
)

func main() {
	claims := new(jwt.Claims)

	var myClaims struct {
		String string    `jwt:"string"`
		Bytes  []byte    `jwt:"bytes"`
		Time   time.Time `jwt:"time"`
		BigInt *big.Int  `jwt:"bigint"`
	}
	myClaims.String = "it is custom claim"
	myClaims.Bytes = []byte("base64-rawurl encoded byte sequence")
	myClaims.Time = time.Unix(1234567890, 0)
	myClaims.BigInt, _ = new(big.Int).SetString("71185727259945196030657158393116523760833600269775786460544228200423405551456", 0)
	if err := claims.EncodeCustom(myClaims); err != nil {
		log.Fatal(err)
	}

	fmt.Println(claims.Raw["string"])
	fmt.Println(claims.Raw["bytes"])
	fmt.Println(claims.Raw["time"])
	fmt.Println(claims.Raw["bigint"])
}
Output:

it is custom claim
YmFzZTY0LXJhd3VybCBlbmNvZGVkIGJ5dGUgc2VxdWVuY2U
1234567890
nWGxne_9WmC6hEr0kuwsxERJxWl7MmkZcDusAxyuf2A

type FindKeyFunc

type FindKeyFunc func(ctx context.Context, header *jws.Header) (key sig.SigningKey, err error)

FindKeyFunc is an adapter to allow the use of ordinary functions as KeyFinder interfaces. If f is a function with the appropriate signature, FindKeyFunc(f) is a KeyFinder that calls f.

func (FindKeyFunc) FindKey

func (f FindKeyFunc) FindKey(ctx context.Context, header *jws.Header) (sig.SigningKey, error)

FindKey calls f(header).

type Issuer added in v0.1.0

type Issuer string

Issuer is a verifier that accepts only the specified issuer.

func (Issuer) VerifyIssuer added in v0.1.0

func (i Issuer) VerifyIssuer(ctx context.Context, iss, sub string) error

type IssuerSubjectVerifier added in v0.1.0

type IssuerSubjectVerifier interface {
	VerifyIssuer(ctx context.Context, iss, sub string) error
}

IssuerSubjectVerifier verifies the issuer and the subject.

type JWKKeyFiner added in v0.0.5

type JWKKeyFiner struct {
	Key *jwk.Key
}

func (*JWKKeyFiner) FindKey added in v0.0.5

func (f *JWKKeyFiner) FindKey(ctx context.Context, header *jws.Header) (sig.SigningKey, error)

type JWKSKeyFinder added in v0.0.5

type JWKSKeyFinder struct {
	JWKS *jwk.Set
}

func (*JWKSKeyFinder) FindKey added in v0.0.5

func (f *JWKSKeyFinder) FindKey(header *jws.Header) (sig.SigningKey, error)

type KeyFinder

type KeyFinder interface {
	FindKey(ctx context.Context, header *jws.Header) (key sig.SigningKey, err error)
}

KeyFinder finds the key used for signing. e.g, you can return a key corresponding to the KID.

type Parser added in v0.1.0

type Parser struct {
	KeyFinder             KeyFinder
	AlgorithmVerifier     AlgorithmVerifier
	IssuerSubjectVerifier IssuerSubjectVerifier
	AudienceVerifier      AudienceVerifier
	// contains filtered or unexported fields
}

Parser is a JWT parser.

func (*Parser) Parse added in v0.1.0

func (p *Parser) Parse(ctx context.Context, data []byte) (*Token, error)

type Token

type Token struct {
	Header *jws.Header
	Claims *Claims
}

Token is a decoded JWT token.

Jump to

Keyboard shortcuts

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