-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Jwt v5 update #9
Conversation
@aldas Can you review this change? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@whkelvin please change this line echo-jwt/.github/workflows/echo.yml Line 28 in 95b0b60
to lets just drop 1.17 and add 1.20 |
allright, this line echo-jwt/.github/workflows/checks.yml Line 17 in 95b0b60
|
it has to be quoted |
ok, I'll merge this and fix these CI things. Thanks @whkelvin |
@aldas I think that the v4.2.0 release should be retracted.
With the current tag, a lot of users may break authentication of their services with a simple A new release as |
I understand what you say but this library (unlike Echo core) does not follow semantic versioning promises. Second paragraph on repo front page/README states that. It does not try to hide that fact. Our intention is not to break things with "trivial" things like middleware fields/function/methods etc but to allow us to be reckless and irresponsible when following We have experience from core with JWT lib (using older p.s. being a bastard - if someone find this thread because of production outage - you can blame me but do not forget that that I am not the one who should have written integration test which will catch this thing easily (my own takeaway from post-mortem/experience with last JWT lib breaking change). |
p.s.s. I'll add more clearer note about the promises to the readme and example for testing handler with middleware |
Thanks for the feedback @aldas!
Just as a small improvement, I think that this statement should be placed somewhere as the comparaison with the middleware in the core. Thanks for your work! |
Voted down. |
@SladeThe there is nothing that requires you use this middleware. 50+% of it is different configuration options. If you absolutely disagree and can not use this lib then try this This is stripped down version of same middleware: func jwtMW(signingKey []byte) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
_, auth, ok := strings.Cut(c.Request().Header.Get("Authorization"), "bearer ")
if !ok {
return echo.NewHTTPError(http.StatusUnauthorized, "authorization header missing or invalid")
}
token, err := jwt.ParseWithClaims(auth, jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
if token.Method.Alg() != "HS256" {
return nil, echo.NewHTTPError(http.StatusUnauthorized, "unexpected jwt signing method")
}
return signingKey, nil
})
if err != nil {
return err
}
if !token.Valid {
return echo.NewHTTPError(http.StatusUnauthorized, "invalid token")
}
c.Set("token", token)
return next(c)
}
}
} Full example: package main
import (
"errors"
"fmt"
"github.com/golang-jwt/jwt/v5"
"github.com/labstack/echo/v4"
"log"
"net/http"
"strings"
)
func jwtMW(signingKey []byte) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
_, auth, ok := strings.Cut(c.Request().Header.Get("Authorization"), "bearer ")
if !ok {
return echo.NewHTTPError(http.StatusUnauthorized, "authorization header missing or invalid")
}
token, err := jwt.ParseWithClaims(auth, jwt.MapClaims{}, func(token *jwt.Token) (interface{}, error) {
if token.Method.Alg() != "HS256" {
return nil, echo.NewHTTPError(http.StatusUnauthorized, "unexpected jwt signing method")
}
return signingKey, nil
})
if err != nil {
return err
}
if !token.Valid {
return echo.NewHTTPError(http.StatusUnauthorized, "invalid token")
}
c.Set("token", token)
return next(c)
}
}
}
func main() {
e := echo.New()
e.Use(jwtMW([]byte("secret")))
e.GET("/test", func(c echo.Context) error {
token := c.Get("token")
return c.JSON(http.StatusOK, fmt.Sprintf("token: %v", token))
})
if err := e.Start(":8080"); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal(err)
}
} Output: x@x:~/code/echo$ curl -H "Authorization: bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" http://localhost:8080/test
"token: \u0026{eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ 0xc0000120a8 map[alg:HS256 typ:JWT] map[admin:true name:John Doe sub:1234567890] [76 149 64 247 147 171 51 177 54 112 22 155 223 68 76 30 177 195 112 71 241 142 134 25 129 225 78 52 88 123 30 4] true}" |
No description provided.