echo-jwt Go Report Card codecov

A JWT middleware for the Echo framework using lestrrat-go/jwx.


go get


Before using the middleware you need to generate an RSA private key (RSASSA-PKCS-v1.5 using SHA-256) to sign and verify the tokens.

openssl genrsa -out private-key.pem 4096

Code example:

package main

import (

	jwx ""

var privateKey *rsa.PrivateKey

func main() {
	e := echo.New()

	e.GET("/", func(c echo.Context) error {
		t := c.Get("token").(jwx.Token)
		return c.JSON(http.StatusOK, t)

	e.POST("/login", func(c echo.Context) error {
		builder := jwx.NewBuilder().
			Claim("name", c.QueryParam("name"))

		token, err := builder.Build()
		if err != nil {
			panic(fmt.Sprintf("failed building token: %v\n", err))

		signed, err := jwx.Sign(token, jwx.WithKey(jwa.RS256, privateKey))
		if err != nil {
			panic(fmt.Sprintf("failed signing token: %v\n", err))

		return c.JSON(http.StatusOK, map[string]string{"access_token": string(signed)})

	key, err := loadPrivateKey("/path/to/private-key.pem")
	if err != nil {
		panic(fmt.Sprintf("failed loading private key: %v\n", err))
	privateKey = key



func loadPrivateKey(path string) (*rsa.PrivateKey, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err

	b, err := io.ReadAll(f)
	if err != nil {
		return nil, err

	block, _ := pem.Decode(b)
	if block == nil {
		return nil, fmt.Errorf("failed to parse PEM block: %v", err)

	key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err

	return key, nil

Getting a token:

curl -X POST http://localhost:1323/login\?name\=alex

Using a token:

curl http://localhost:1323/ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOj...'

Exempt routes

By default, all routes except POST /login will require a token in the Authorization header or as a cookie with the key access_token.

You may define some additional exempted routes and methods that don’t require a token:

    ExemptRoutes: map[string][]string{
        "/":          {http.MethodGet},
        "/login":     {http.MethodPost},
        "/users":     {http.MethodPost, http.MethodGet},
        "/users/:id": {http.MethodGet},
    Key: key,


type Config struct {
    // Skipper defines a function to skip middleware.
    Skipper middleware.Skipper

    // Key defines the RSA key used to verify tokens.
    // Required.
    Key interface{}

    // ExemptRoutes defines routes and methods that don't require tokens.
    // Optional. Defaults to /login [POST].
    ExemptRoutes map[string][]string

    // ExemptMethods defines methods that don't require tokens.
    // Optional. Defaults to [OPTIONS].
    ExemptMethods []string

    // OptionalRoutes defines routes and methods that
    // can optionally require a token.
    // Optional.
    OptionalRoutes map[string][]string

    // ParseTokenFunc defines a function used to decode tokens.
    // Optional.
    ParseTokenFunc func(string, []jwt.ParseOption) (jwt.Token, error)

    // AfterParseFunc defines a function that will run after
    // the ParseTokenFunc has successfully run.
    // Optional.
    AfterParseFunc func(echo.Context, jwt.Token) *echo.HTTPError

    // Options defines jwt.ParseOption options for parsing tokens.
    // Optional. Defaults [jwt.WithValidate(true)].
    Options []jwt.ParseOption

    // ContextKey defines the key that will be used to store the token
    // on the echo.Context when the token is successfully parsed.
    // Optional. Defaults to "token".
    ContextKey string

    // CookieKey defines the key that will be used to read the token
    // from an HTTP cookie.
    // Optional. Defaults to "access_token".
    CookieKey string

    // AuthHeader defines the HTTP header that will be used to
    // read the token from.
    // Optional. Defaults to "Authorization".
    AuthHeader string


View Github