GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - labstack/echo-jwt: JWT middleware for Echo framework

BranchesTags
Open more actions menu

Latest commit

 

History

38 Commits
38 Commits

Folders and files

NameName
Last commit message
Last commit date
.github
.github
 
 
.editorconfig
.editorconfig
 
 
.gitattributes
.gitattributes
 
 
.gitignore
.gitignore
 
 
CHANGELOG.md
CHANGELOG.md
 
 
LICENSE
LICENSE
 
 
Makefile
Makefile
 
 
README.md
README.md
 
 
codecov.yml
codecov.yml
 
 
go.mod
go.mod
 
 
go.sum
go.sum
 
 
jwt.go
jwt.go
 
 
jwt_benchmark_test.go
jwt_benchmark_test.go
 
 
jwt_external_test.go
jwt_external_test.go
 
 
jwt_integration_test.go
jwt_integration_test.go
 
 
jwt_test.go
jwt_test.go
 
 

Repository files navigation

Sourcegraph GoDoc Go Report Card Codecov License

Echo JWT middleware

JWT middleware for Echo framework. This middleware uses by default golang-jwt/jwt/v5 as JWT implementation.

Versioning

This repository does not use semantic versioning. MAJOR version tracks which Echo version should be used. MINOR version tracks API changes (possibly backwards incompatible) and PATCH version is incremented for fixes.

NB: When golang-jwt MAJOR version changes this library will release MINOR version with breaking change. Always add at least one integration test in your project.

For Echo v5 use v5.x.y releases. Minimal needed Echo versions:

  • v5.0.0 needs Echo v5.0.0+
  • v4.0.0 needs Echo v4.7.0+

main branch is compatible with the latest Echo version.

Usage

Add JWT middleware dependency with go modules

go get github.com/labstack/echo-jwt/v5

Use as import statement

import "github.com/labstack/echo-jwt/v5"

Add middleware in simplified form, by providing only the secret key

e.Use(echojwt.JWT([]byte("secret")))

Add middleware with configuration options

e.Use(echojwt.WithConfig(echojwt.Config{
  // ...
  SigningKey:             []byte("secret"),
  // ...
}))

Extract token in handler

import "github.com/golang-jwt/jwt/v5"

// ...

e.GET("/", func(c *echo.Context) error {
  token, err := echo.ContextGet[*jwt.Token](c,"user")
  if err != nil {
    return echo.ErrUnauthorized.Wrap(err)
  }
  claims, ok := token.Claims.(jwt.MapClaims) // by default claims is of type `jwt.MapClaims`
  if !ok {
    return errors.New("failed to cast claims as jwt.MapClaims")
  }
  return c.JSON(http.StatusOK, claims)
})

IMPORTANT: Integration Testing with JWT Library

Ensure that your project includes at least one integration test to detect changes in major versions of the golang-jwt/jwt library early. This is crucial because type assertions like token := c.Get("user").(*jwt.Token) may fail silently if the imported version of the JWT library (e.g., import "github.com/golang-jwt/jwt/v5") differs from the version used internally by dependencies (e.g., echo-jwt may now use v6). Such discrepancies can lead to invalid casts, causing your handlers to panic or throw errors. Integration tests help safeguard against these version mismatches.

func TestIntegrationMiddlewareWithHandler(t *testing.T) {
	e := echo.New()
	e.Use(echojwt.WithConfig(echojwt.Config{
		SigningKey: []byte("secret"),
	}))

  // use handler that gets token from context to fail your CI flow when `golang-jwt/jwt` library version changes 
  // a) `token, ok := c.Get("user").(*jwt.Token)`
  // b) `token := c.Get("user").(*jwt.Token)`
	e.GET("/example", exampleHandler) 

	req := httptest.NewRequest(http.MethodGet, "/example", nil)
	req.Header.Set(echo.HeaderAuthorization, "Bearer <TOKEN>")
	res := httptest.NewRecorder()

	e.ServeHTTP(res, req)
	
	if res.Code != 200 {
		t.Failed()
	}
}

Full example

package main

import (
  "errors"
  "log/slog"

  "github.com/golang-jwt/jwt/v5"
  "github.com/labstack/echo-jwt/v5"
  "github.com/labstack/echo/v5"
  "github.com/labstack/echo/v5/middleware"

  "net/http"
)

func main() {
  e := echo.New()
  e.Use(middleware.RequestLogger())
  e.Use(middleware.Recover())

  e.Use(echojwt.WithConfig(echojwt.Config{
    SigningKey: []byte("secret"),
  }))

  e.GET("/", func(c *echo.Context) error {
    token, err := echo.ContextGet[*jwt.Token](c, "user")
    if err != nil {
      return echo.ErrUnauthorized.Wrap(err)
    }
    claims, ok := token.Claims.(jwt.MapClaims) // by default claims is of type `jwt.MapClaims`
    if !ok {
      return errors.New("failed to cast claims as jwt.MapClaims")
    }
    return c.JSON(http.StatusOK, claims)
  })

  if err := e.Start(":8080"); err != nil {
    slog.Error("Failed to start server", "error", err)
  }
}

Test with

curl -v -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" http://localhost:8080

Output should be

* Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.81.0
> Accept: */*
> Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Content-Type: application/json; charset=UTF-8
< Date: Sun, 27 Nov 2022 21:34:17 GMT
< Content-Length: 52
< 
{"admin":true,"name":"John Doe","sub":"1234567890"}

About

JWT middleware for Echo framework

Topics

echoecho-frameworkjwtmiddleware

Resources

Readme
MIT license
Activity
Custom properties

Stars

125 stars

Watchers

3 watching

Forks

14 forks
Report repository

Releases

Used by

Contributors

Languages

You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.