JSON Web Token library

API Documentation Build Status

About

… a JSON Web Token (JWT) library for the Go programming language.

  • Feature complete
  • Full test coverage
  • Dependency free
  • Key management

The API enforces secure use by design. Unsigned tokens are rejected. No support for encrypted tokens either—use wire encryption instead.

This is free and unencumbered software released into the public domain.

Introduction

Tokens encapsulate signed statements called claims. A claim is a named JSON value. Applications using JWTs should define which specific claims they use and when they are required or optional.

var claims jwt.Claims
claims.Subject = "alice"
claims.Issued  = jwt.NewNumericTime(time.Now().Round(time.Second))
claims.Set     = map[string]interface{}{"email_verified": false}
// issue a JWT
token, err := claims.EdDSASign(JWTPrivateKey)

Tokens consists of printable ASCII characters, e.g., eyJhbGciOiJFUzI1NiJ9.eyJzdWIiOiJha3JpZWdlciIsInByZWZpeCI6IkRyLiJ9.RTOboYsLW7zXFJyXtIypOmXfuRGVT_FpDUTs2TOuK73qZKm56JcESfsl_etnBsl7W80TXE5l5qecrMizh3XYmw. Secured resources can use such tokens to determine the respective permissions. Note how the verification process is self-contained with just a public key.

// verify a JWT
claims, err := jwt.EdDSACheck(token, JWTPublicKey)
if err != nil {
	log.Print("credentials denied with ", err)
	return
}
if !claims.Valid(time.Now()) {
	log.Print("credential time constraints exceeded")
	return
}

log.Print("hello ", claims.Subject)
if verified, _ := claims.Set["email_verified"].(bool); !verified {
	log.Print("e-mail confirmation pending")
}

Commonly, agents receive a JWT uppon authentication/login. Then, that token is included with requests to the secured resources, as a proof of authority. Token access is “eyes only” in such scenario. Include and enforce more context detail with claims to further reduce risk. E.g., a session identifier or a fingerprint of the client's TLS key can prevent usage of any hijacked tokens.

High-Level API

Server-side security can be applied with a standard http.Handler setup. The following example denies requests to MyAPI when the JWT is not valid, or when the JWT is missing either the subject, formatted name or roles claim.

// define trusted credentials
var keys jwt.KeyRegister
n, err := keys.LoadPEM(text, nil)
if err != nil {
	log.Fatal(err)
}
log.Print("setup with ", n, " JWT keys")

http.Handle("/api/v1", &jwt.Handler{
	Target: MyAPI, // protected HTTP handler
	Keys:   keys,

	// map two claims to HTTP headers
	HeaderPrefix: "X-Verified-",
	HeaderBinding: map[string]string{
		"sub": "X-Verified-User", // registered [standard] claim
		"fn":  "X-Verified-Name", // private [custom] claim
	},

	// map another claim with custom logic
	Func: func(w http.ResponseWriter, req *http.Request, claims *jwt.Claims) (pass bool) {
		log.Printf("got a valid JWT %q for %q", claims.ID, claims.Audiences)

		// map role enumeration
		s, ok := claims.String("roles")
		if !ok {
			http.Error(w, "jwt: want roles claim as a string", http.StatusForbidden)
			return false
		}
		req.Header["X-Verified-Roles"] = strings.Fields(s)

		return true
	},
})

When all applicable JWT claims are mapped to HTTP request headers, then the service logic can stay free of verification code, plus easier unit testing.

// Greeting is a standard HTTP handler fuction.
func Greeting(w http.ResponseWriter, req *http.Request) {
	fmt.Fprintf(w, "Hello %s!\n", req.Header.Get("X-Verified-Name"))
	fmt.Fprintf(w, "You are authorized as %s.\n", req.Header.Get("X-Verified-User"))
}

The validated Claims object may also be exposed through the request context.

Performance

The following results were measured with Go 1.15RC2 on an Intel i5-7500.

name                      time/op
ECDSA/sign-ES256-4        27.9µs ± 0%
ECDSA/sign-ES384-4        4.36ms ± 0%
ECDSA/sign-ES512-4        7.66ms ± 0%
ECDSA/check-ES256-4       83.1µs ± 1%
ECDSA/check-ES384-4       8.61ms ± 0%
ECDSA/check-ES512-4       14.9ms ± 0%
EdDSA/sign-EdDSA-4        51.6µs ± 0%
EdDSA/check-EdDSA-4        138µs ± 1%
HMAC/sign-HS256-4         2.03µs ± 1%
HMAC/sign-HS256-reuse-4   1.42µs ± 1%
HMAC/sign-HS384-4         2.32µs ± 0%
HMAC/sign-HS384-reuse-4   1.39µs ± 0%
HMAC/sign-HS512-4         2.35µs ± 1%
HMAC/sign-HS512-reuse-4   1.42µs ± 0%
HMAC/check-HS256-4        4.14µs ± 0%
HMAC/check-HS256-reuse-4  3.51µs ± 1%
HMAC/check-HS384-4        4.47µs ± 1%
HMAC/check-HS384-reuse-4  3.53µs ± 0%
HMAC/check-HS512-4        4.53µs ± 1%
HMAC/check-HS512-reuse-4  3.57µs ± 0%
RSA/sign-1024-bit-4        327µs ± 0%
RSA/sign-2048-bit-4       1.49ms ± 0%
RSA/sign-4096-bit-4       8.14ms ± 1%
RSA/check-1024-bit-4      29.0µs ± 0%
RSA/check-2048-bit-4      64.6µs ± 1%
RSA/check-4096-bit-4       173µs ± 1%

EdDSA [Ed25519] produces small signatures and it performs well.

Standard Compliance

  • RFC 2617: “HTTP Authentication”
  • RFC 6750: “The OAuth 2.0 Authorization Framework: Bearer Token Usage”
  • RFC 7468: “Textual Encodings of PKIX, PKCS, and CMS Structures”
  • RFC 7515: “JSON Web Signature (JWS)”
  • RFC 7517: “JSON Web Key (JWK)”
  • RFC 7518: “JSON Web Algorithms (JWA)”
  • RFC 7519: “JSON Web Token (JWT)”
  • RFC 8037: “CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)”

JWT.io

Owner
Pascal S. de Kloe
freelance engineer
Pascal S. de Kloe
Comments
  • Abstract signing

    Abstract signing

    Feature Request. I can make a call to Azure keyvault to sign and what I get back are the following ;

    1. kid
    2. base64 url encoded signature
    3. alg, i.e. "RSA256" passed in

    Could you think about putting the signing stuff into an interface and letting me implement that on my end. I would still expect your code to construct the JWT ({0}.{1}.{signature})

    That way we could also reduce what looks like redundant code in all the *Sign() functions.

    my POC function looks like this, and would change based upon the interface requirements of your engine;

    // HARD CODED to SHA256 at the moment
    
    func RSA256AzureSign(ctx context.Context, data []byte) (kid *string, signature *string, err error) {
    	keyClient := getKeysClient()
    	digest := crypto.SHA256.New()
    	digest.Write(data)
    	h := digest.Sum(nil)
    	sEnc := b64.StdEncoding.EncodeToString(h)
    
    	keyOperationResult, err := keyClient.Sign(ctx, "https://P7KeyValut.vault.azure.net/", "P7IdentityServer4SelfSigned", "", keyvault.KeySignParameters{
    		Algorithm: keyvault.RS256,
    		Value:     &sEnc,
    	})
    	if err != nil {
    		return
    	}
    	return keyOperationResult.Kid, keyOperationResult.Result, nil
    }
    

    The call to azure picks the latest version of the cert and signs for me, returning the kid and the base64 signature.

  • Missing Ed25519 package

    Missing Ed25519 package

    Hey there! Love your package. It's very simple and straight-forward. I prefer it to other JWT packages thanks to its API. Great job!

    I only have one problem. I have jwt in my project and it's in my go.mod and in go.sum. Every time I try to run go test -v -count=1 ./... in my root directory, it complains about jwt's imported library and fails:

    myproject:master* λ go test -v -count=1 ./...
    ../../pascaldekloe/jwt/check.go:6:2: cannot find package "crypto/ed25519" in any of:
    	/usr/lib/go/src/crypto/ed25519 (from $GOROOT)
    	/home/myusername/go/src/crypto/ed25519 (from $GOPATH)
    

    crypto/ed25519 exists on my system:

    ed25519:master λ pwd
    /home/myusername/go/src/golang.org/x/crypto/ed25519
    

    Is there something wrong with my system variables or import paths?

    This problem doesn't occur with any other packages.

    Thanks!

  • Feature/example request

    Feature/example request

    This library looks very promising, however, to make it really useful, I have two questions:

    1. can you provide a convenient method to convert a JSON string into the jwt.Claims structure?
    2. how can I verify a jwt token if I have a private string typed password?

    For 1, you can argue that it's not this project's responsibility to do it, that's fine. But for 2, I cannot believe it's not documented in the readme.md. This is the most fundamental use of jwt. I think if your project is better documented, this project will gain 50x more popularity. I have been here several times and was turned off by lacking of useful examples every time. This time I finally decided to open this ticket. Thanks.

  • Audiences are represented as string if claims.Set is used

    Audiences are represented as string if claims.Set is used

    Hi, at first, thank you for this awesome library! But whenever I use claims.Set = map[string]interface{}{"role": "userrole",} audiences are stated as a string instead of an array.

    E.g.:

    {
      "aud": "audience.org",
      "exp": 1897992150.1938002,
      "iat": 1582275750,
      "iss": "issuer.org",
      "role": "userrole",
      "sub": "0ff88b48-231c-4862-8fcf-56c7fce32400"
    }
    

    vs.

    {
      "aud": [
               "audience.org"
             ],
      "exp": 1897992150.1938002,
      "iat": 1582275750,
      "iss": "issuer.org",
      "sub": "0ff88b48-231c-4862-8fcf-56c7fce32400"
    }
    
  • Unexported errors

    Unexported errors

    I'm curious as to why some of potential return errors from HMACCheckHeader aren't exported. This includes errAuthHeader, and errAuthSchema. Since they aren't exported I can't compare against them in my middleware.

    I need to handle differently the situations where an invalid token is submitted and no token is submitted. I could just duplicate the code, but those errors are already being returned. To take advantage of them, I'd need to do string comparison, which is frowned upon.

    Any interest in exporting these errors?

  • write some performance benchmark vs dgrijalva/jwt-go

    write some performance benchmark vs dgrijalva/jwt-go

    thanks for you lib. i'm use jwt and provide ed25519 for https://github.com/dgrijalva/jwt-go/pull/366 but as it now not merged and i don't understand how long this can takes, can you provide simple benchmark of you lib vs https://github.com/dgrijalva/jwt-go ? may be other can use it to decide what lib to use for jwt ?

  • How to encode/decode ed25519 keys

    How to encode/decode ed25519 keys

    Must these be stored in binary in a file? I want to persist them to a file, but so far have not been able to encode/decode as PEM, or even base64. They are always corrupt when I read them back in.

    If I try to generate the keys from openssl or ssh-keygen, I'm also not able to read those in as valid ed25519 keys.

    The test I use is to generate them in Go, then try to encode them, decode them, and re-run a sign/verify.

  • Remove goe dependency

    Remove goe dependency

    Thanks for your work on this package.

    In the README it says the package uses no third-party dependencies, but the go.mod file lists the dependency github.com/pascaldekloe/goe.

    From a quick check it looks like the only place goe is being used is the following line: https://github.com/pascaldekloe/jwt/blob/fcba0b3ef7ede11014a95c26e2ecea73a94e5013/x/x_test.go#L134

    I was wondering if the test could be refactored to inline any necessary code, instead of pulling through the whole dependency?

  • Use semver to support go module

    Use semver to support go module

    If you try to use this lib with go 1.11's module system the latest release it will download is v1.2.1. Go modules require tags to be formatted as vx.y.z where x is MAJOR, y is MINOR and z is the PATCH number. Could you migrate tags and releases to semver-formatted strings?

  • Crypto Go :we are a research group to help developers build secure applications.

    Crypto Go :we are a research group to help developers build secure applications.

    Hi, we are a research group to help developers build secure applications. We designed a cryptographic misuse detector (i.e., CryptoGo) on Go language. We found your great public repository from Github, and several security issues detected by CryptoGo are shown in the following. Note that the cryptographic algorithms are categorized with two aspects: security strength and security vulnerability based on NIST Special Publication 800-57 and other public publications. Moreover, CryptoGo defined certain rules derived from the APIs of Go cryptographic library and other popular cryptographic misuse detectors. The specific security issues we found are as follows: Location: sign.go:174; Broken rule: RSASSA-PKCS1-v1_5 is deprecated; We wish the above security issues could truly help you to build a secure application. If you have any concern or suggestion, please feel free to contact us, we are looking forward to your reply. Thanks.

  • Add Claim Field Validation

    Add Claim Field Validation

    While this library does provide methods for checking the signature (such as HMCACheck(<token>, <secret>)) and for checking that the token hasn't expired (*Claims.Valid(time.Time)), it doesn't provide validators for validating each claim in the JWT payload. This PR adds the ability to create a validator for each field to then be used along with the Claims in ValidatePayloadClaims.

    As an example:

    
    // Create your field validators. For all minus the TimeFieldValidator, just pass in the expected
    // results. For the TimeFieldValidator, pass in the time that all time fields must be valid for. (Does
    // not have to be time.Now())
    issValidator := jwt.IssuerValidator("testIssuer")
    audValidator := jwt.AudiencesValidator([]string{"testAudienceOne", "testAudienceTwo"})
    subValidator := jwt.SubjectValidator(strconv.Itoa(1234))
    timeValidator := jwt.TimeFieldValidator(time.Now())
    idValidator := jwt.IdValidator(strconv.Itoa(5678))
    
    // Not only are there validators for the Registered claims, but there is also a validator for custom claims.
    // Just pass in the expected value, and the name of the custom claim field.
    customFieldValidator  := jwt.CustomClaimValidator("expectedCustomFieldValue", "customClaimFieldName")
    
    // Pass in the token's claims and your field validators. tokenClaims is *Claims from the created token
    err = jwt.ValidatePayloadClaims(tokenClaims, issValidator, audValidator, subValidator, timeValidator, idValidator, customFieldValidator)
    
Go-gin-jwt - Secure web api using jwt token and caching mechanism

Project Description This project demonstrate how to create api and secure it wit

Jan 27, 2022
⛩️ Go library for protecting HTTP handlers with authorization bearer token.

G8, pronounced Gate, is a simple Go library for protecting HTTP handlers with tokens. Tired of constantly re-implementing a security layer for each

Nov 14, 2022
Small Lambda function which performs a Aws:Sts:AssumeRole based on the presented JWT-Token

About This implements a AWS Lambda handler which takes a JWT-Token, validates it and then performs a Aws:Sts:AssumeRole based on preconfigured rules.

Aug 8, 2022
Golang implementation of JWT and Refresh Token

Fiber and JWT with Refresh Token Repo ini adalah demostrasi JWT support refresh token tanpa menggunakan storage Branch Main: unlimited refresh token R

Dec 18, 2022
Key-Checker - Go scripts for checking API key / access token validity
Key-Checker - Go scripts for checking API key / access token validity

Key-Checker Go scripts for checking API key / access token validity Update V1.0.0 ?? Added 37 checkers! Screenshoot ?? How to Install go get github.co

Dec 19, 2022
A demo using go and redis to implement a token manager

使用go-redis实现一个令牌管理器 需求描述 假设我们当前的所有服务需要一个第三方的认证,认证形式为:在发送请求的时候带上第三方颁发的令牌,该令牌具有一个时效性 第三方的令牌可以通过某个接口获取,但是该接口做了单位时间内的同一ip的请求频率的限制,因此在并发的场景下,我们需要控制令牌获取接口的频

Oct 19, 2021
A very simple HTTP reverse proxy that checks that requests contain a valid secret as a bearer token

bearproxy -- Authorization enforcing HTTP reverse proxy Bearproxy is a very simple HTTP reverse proxy that checks that requests contain a valid secret

Nov 11, 2021
Go module that allows you to authenticate to Azure with a well known client ID using interactive logon and grab the token

azureimposter Go module that pretends to be any clientID and grabs an authentication token from Azure using interactive login (w/mfa if enabled) and r

Dec 14, 2022
Cache oci login token for kubectl

oci-token-cache Cache oci login token. This command cache oci login token into ~/.oci/token-cache.json and re-use for kubectl. Usage Currently, your ~

Nov 20, 2021
Backend Development Rest Api Project for book management system. Used Features like redis, jwt token,validation and authorization.

Golang-restapi-project Simple Rest Api Project with Authentication, Autherization,Validation and Connection with redis File Structure ├── cache │ ├──

May 25, 2022
A command-line tool to visualize a JWT token's content, written in Go

jat A command-line tool to visualize a JWT token's content, written in Go. Usage jat <some-jwt> Install Navigate to the Releases page; Download the co

Jan 6, 2022
Go module with token package to request Azure Resource Manager and Azure Graph tokens.

azAUTH Go module with token package to request Azure Resource Manager and Azure Graph tokens. prerequisites Install azure cli: https://docs.microsoft.

Dec 1, 2021
A simple user identify template with jwt token and gin, toy project

Simple Docs Register url : /api/auth/register param type value name string username password string password mailbox string mailbox response: { "sta

Dec 31, 2021
fido-ident: a cli tool for getting the attestation certificate from a fido token.

fido-ident fido-ident is a cli tool for getting the attestation certificate from a fido token. fido-ident will print the raw certificate and the human

Jan 28, 2022
Oct 1, 2022
GitHub App Token Generator

A simple github action written in go to retrieve an installation access token for an app installed into an organization.

Jan 5, 2023
An example module for k6.io to get a cognito access token using USER_SRP_AUTH flow.

xk6-cognito An example module for k6.io to get a cognito access token using USER_SRP_AUTH flow. See: to create k6 extension: https://github.c

Nov 15, 2022
Verifier - Golang JWT token verifier with storage(default Redis)

verifier Golang JWT token verifier with storage(default Redis) Usage go get -u g

Nov 6, 2022
A simple and lightweight library for creating, formatting, manipulating, signing, and validating JSON Web Tokens in Go.

GoJWT - JSON Web Tokens in Go GoJWT is a simple and lightweight library for creating, formatting, manipulating, signing and validating Json Web Tokens

Nov 15, 2022