Branch master
is unstable, always use tagged versions. That way it is possible to differentiate pre-release tags from production ones.
In other words, API changes all the time in master
. It's a place for public experiment. Thus, make use of the latest stable version via Go modules.
This package is a JWT signer, verifier and validator for Go (or Golang).
Although there are many JWT packages out there for Go, many lack support for some signing, verifying or validation methods and, when they don't, they're overcomplicated. This package tries to mimic the ease of use from Node JWT library's API while following the Effective Go guidelines.
Support for JWE isn't provided. Instead, JWS is used, narrowed down to the JWT specification.
SHA-256 | SHA-384 | SHA-512 | |
---|---|---|---|
HMAC | ✔️ | ✔️ | ✔️ |
RSA | ✔️ | ✔️ | ✔️ |
RSA-PSS | ✔️ | ✔️ | ✔️ |
ECDSA | ✔️ | ✔️ | ✔️ |
EdDSA | ➖ | ➖ | ✔️ |
Full documentation here.
go get -u github.com/gbrlsnchs/jwt/v3
import (
// ...
"github.com/gbrlsnchs/jwt/v3"
)
now := time.Now()
hs256 := jwt.NewHMAC(jwt.SHA256, []byte("secret"))
h := jwt.Header{KeyID: "kid"}
p := jwt.Payload{
Issuer: "gbrlsnchs",
Subject: "someone",
Audience: jwt.Audience{"https://golang.org", "https://jwt.io"},
ExpirationTime: now.Add(24 * 30 * 12 * time.Hour).Unix(),
NotBefore: now.Add(30 * time.Minute).Unix(),
IssuedAt: now.Unix(),
JWTID: "foobar",
}
token, err := jwt.Sign(h, p, hs256)
if err != nil {
// Handle error.
}
log.Printf("token = %s", token)
type CustomPayload struct {
jwt.Payload
IsLoggedIn bool `json:"isLoggedIn"`
CustomField string `json:"customField,omitempty"`
}
now := time.Now()
hs256 := jwt.NewHMAC(jwt.SHA256, []byte("secret"))
h := jwt.Header{KeyID: "kid"}
p := CustomPayload{
Payload: jwt.Payload{
Issuer: "gbrlsnchs",
Subject: "someone",
Audience: jwt.Audience{"https://golang.org", "https://jwt.io"},
ExpirationTime: now.Add(24 * 30 * 12 * time.Hour).Unix(),
NotBefore: now.Add(30 * time.Minute).Unix(),
IssuedAt: now.Unix(),
JWTID: "foobar",
},
IsLoggedIn: true,
CustomField: "myCustomField",
}
token, err := jwt.Sign(h, p, hs256)
if err != nil {
// Handle error.
}
log.Printf("token = %s", token)
now := time.Now()
hs256 := jwt.NewHMAC(jwt.SHA256, []byte("secret"))
token := []byte("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." +
"eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ." +
"lZ1zDoGNAv3u-OclJtnoQKejE8_viHlMtGlAxE8AE0Q")
raw, err := jwt.Parse(token)
if err != nil {
// Handle error.
}
if err = raw.Verify(hs256); err != nil {
// Handle error.
}
var (
h jwt.Header
p CustomPayload
)
if h, err = raw.Decode(&p); err != nil {
// Handle error.
}
fmt.Println(h.Algorithm)
fmt.Println(h.KeyID)
iatValidator := jwt.IssuedAtValidator(now)
expValidator := jwt.ExpirationTimeValidator(now, true)
audValidator := jwt.AudienceValidator(jwt.Audience{"https://golang.org", "https://jwt.io", "https://google.com", "https://reddit.com"})
if err := p.Validate(iatValidator, expValidator, audValidator); err != nil {
switch err {
case jwt.ErrIatValidation:
// handle "iat" validation error
case jwt.ErrExpValidation:
// handle "exp" validation error
case jwt.ErrAudValidation:
// handle "aud" validation error
}
}
- For bugs and opinions, please open an issue
- For pushing changes, please open a pull request