gofiber / jwt Goto Github PK
View Code? Open in Web Editor NEW⚠️ Deprecated repository, available within Fiber Contrib.
Home Page: https://github.com/gofiber/contrib/tree/main/jwt
License: MIT License
⚠️ Deprecated repository, available within Fiber Contrib.
Home Page: https://github.com/gofiber/contrib/tree/main/jwt
License: MIT License
I found this: gofiber/fiber#207
but it seems that if I use wildcard routing, then I can't use this middleware, I just could handle jwt authentication in custom handler.
I want this middleware works with wildcard routing, anybody could tell me how?
thanks!
I was wondering if there is any way to invalidate a token beside the expire time.
app.Use("/ws", jwtware.New(jwtware.Config{SigningKey: yourKey})) // <-- comment this line would works fine.
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
...
}))
app.Listen(3000)
Access ws://localhsot:3000/ws will always return WebSocketError: Received unexpected status code (400 Bad Request)
After commenting jwtware or replacing jwtware with my own jwt parsing&validating middleware, it worked fine.
After add ErrorHandler, it would always run into ErrorHandler.
Does this middleware can't work with websocket middleware?
I use the following code to get username and user id in handler:
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
userID := claims["user_id"].(string)
userName := claims["username"].(string)
But with error below:
panic: interface conversion: interface {} is nil, not *jwt.Token
Can anyone fix it?
Thank you very much!
hi, Recently i was developing a fiber app to support openID login, and the access token i receive is jwt which signed by IDP using their JWKS json.
Can i know how i can use this middleware to valid their access token(jwt) via JWKS?
i saw that the jwt property have signingKeys property which contain kid similar to format in JWKS, can i just put that jwks json to that property?
I took the following example as a guide,
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
name := claims["name"].(string)
but unlike the example, the key I am looking for is not string, but int64 (It is an integer: 1, 2, 3). Unfortunately, I get the following error if I keep the .(string)
cannot convert claims["bar"] (type interface {}) to type string: need type assertion
and the following error, if I replace the .(string) for .(int64)
panic: interface conversion: interface {} is float64, not string
So, how can I get my number as int64 instead of string or this float64 (??) that it is guessing to be?
Example Given here is wrong:- https://github.com/gofiber/jwt#example
func restricted(c *fiber.Ctx) {
user := c.Locals("user").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
name := claims["name"].(string)
c.Send("Welcome " + name)
}
It throws an error: interface conversion: interface {} is map[string]interface {}, not string
module github.com/gofiber/jwt/v2
shoud be github.com/gofiber/jwt/v3
Hello,
I was wondering if it's and intended behavior...
(Code may be better to explain)
The default error handler is written
if cfg.ErrorHandler == nil {
cfg.ErrorHandler = func(c *fiber.Ctx, err error) error {
if err.Error() == "Missing or malformed JWT" {
return c.Status(fiber.StatusBadRequest).SendString("Missing or malformed JWT")
} else {
return c.Status(fiber.StatusUnauthorized).SendString("Invalid or expired JWT")
}
}
}
This way the error is not processed trough the app error handler
Should it not be that way to be processed by any application level error handler by default?
if cfg.ErrorHandler == nil {
cfg.ErrorHandler = func(c *fiber.Ctx, err error) error {
if err.Error() == "Missing or malformed JWT" {
return fiber.NewError(fiber.StatusBadRequest, "Missing or malformed JWT")
} else {
return fiber.NewError(fiber.StatusUnauthorized, "Invalid or expired JWT")
}
}
}
Not sure if i am clear enough 😅
Hi Fenny,
Thank you for your well-organized library.
Could you please publish v0.0.3 little bit earlier with jwtware?
Importing fiber as ".././fiber" disables jwt build using mod.
Sorry if I am disturbing you with tiny stuff, but this has possibility to make many newcomers like me retreat.
'jwtware' looks also good to me.
Hi, I have a quick question regarding exp
claim in a token. I see in the example that you add it on a token creation, however I'm having trouble finding how it's handled. Is it automatically handled? Or do I need to insert some sort of function that checks it?
The README mentions that the config property KeyRefreshUnknownKID
is a boolean defaulting to false, but in code the field on Config
has type *bool
and is referenced in exactly one place, inside of KeySet.getKey
:
jsonKey, ok = j.Keys[kid]
j.mux.RUnlock()
// Check if the key was present.
if !ok {
// Check to see if configured to refresh on unknown kid.
if *j.Config.KeyRefreshUnknownKID {
Thus, if you don't specify a non-nil
value for this property and you reach this line because you did provide a value for KeySetURL
, your program will panic. I believe we've seen this in testing.
What we could do, and what seems in line with the use of other pointer-valued config properties in this file, is change the conditional to
if j.Config.KeyRefreshUnknownKID != nil && *j.Config.KeyRefreshUnknownKID {
Does the library comply with https://datatracker.ietf.org/doc/html/rfc7519?
Seems exp
in jwt.MapClaims
is not validated.
In my test, after a token expired, it can still be used.
I've check the source code of jwtware.New()
, seems there is no where exp
is checked. Or, did I missed something?
The token being generated is ok, because I parsed the token and check the exp
field, the value is correct.
The desired behavior is that, after the token expired, server should return http code like 401
.
BTW, I tested it in both v3.2.11
and v3.2.12
.
There have been some improvements to github.com/MicahParks/keyfunc
since this project first supported JWT verification from JWK Sets.
Two notable ones are:
github.com/MicahParks/keyfunc
only imports github.com/golang-jwt/jwt
now.kty
header value. This header value is required by the RFC whereas the previous alg
value is optional in a JWK Set.There are a couple others, such as support for given keys (like HMAC bytes) and EdDSA support.
Additionally, some bug fixes have occurred. I see some of the bugs are still present in this project.
jwt.KeySet
exports a field called Keys
. This field is a map that can cause panic: fatal error: concurrent map read and map write
. This would happen when a JWK Set is being refreshed and the map is being read at the same time.rawJWK.precomputed
field triggered by two JWTs using the same kid
being parsed at the same time, if it's the first time that kid
has been seen since the last refresh. See this commit.This issue could be solved by updating the keyfunc code in this project or switching to github.com/MicahParks/keyfunc
. I'd be happy to make a PR to do the latter, if that's a desirable solution 🙂
(github.com/MicahParks/keyfunc
has just released v1.0.0
and I intend to avoid /v2
and beyond.)
We used Fiber in a use case where we get a JWT token in a custom header field from an auth platform like this
{
x-custom-jwt: <mytoken>
}
It seems like can not extract this structure via the fiber JWT middleware as it expects a auth scheme and if not given it crops the first character of the key as it expecs <AuthScheme> <Token>
.
See:
Line 39 in 1a9806c
Suggestion: Either we check if AuthScheme is empty or we trim the token and do not crop with +1
Filter has memory overflow, and the program directly to the terminal
Hi Fenny,
Thank you for your excellent library.
I currently added jwtware as package name in main_test.go
to avoid this error message: found packages jwtware (main.go) and jwt (main_test.go)
.
Sorry if I am disturbing you with tiny stuff, but this has possibility to make many newcomers like me retreat.
Currently on successful validation token is always saved to ctx.Locals()
, but I'm not sure it's necessary, as if we can always get this information from the ctx
anyway, either headers, or cookies or URL params. What might be valuable is to have claims saved instead.
And in any case, we should not decide, but rather give a developer an option on how to treat this situation – the best would be to update the signature of SuccessHandler
and pass a JWT
there. And in case if a developer need it – he / she could save information that they need where they want. While today it's even impossible to switch off this behavior.
Its possible to use multiple extractors by example from cookie and Header at the same time
I'm using jwtware to validate user jwt, but I'd like to extract the user_id from the jwt payload and append it to the request header, I could implement my own middleware I just wanna ask is there already a feature like this?
Thanks in advance <3
Doesn't this break the code tho? because now token
is used before it was created.
Ex:
// Set claims ('token' does not exist here)
claims := token.Claims.(jwt.MapClaims)
//...
// Create token
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
Originally posted by @iSLC in #65 (comment)
I'm trying to use middleware as optional in unauthenticated routes
And if user sending token then I can fetch claims
if token not present in the header then I can abort
How can I have refresh token when user authenticated?
I currently added jwtware "github.com/gofiber/jwt"
to avoid the name conflict with the official jwt
package, this might be something that could be a little bit cleaner.
The upstream JWT package, github.com/golang-jwt/jwt/4
has been updated to /v5
. See this release.
Perhaps now would be a good time to use github.com/MicahParks/keyfunc/v2
. Code from the keyfunc
pre-release was added in this pull request, but this project still holds bugs from that version. Using github.com/MicahParks/keyfunc/v2
would also help resolve:
Could you illustrate with example how to get username, user id from claims when working in handlers?
Thank you very much!
I have these files:
In loginController.go
func Login(c *fiber.Ctx) error {
........
var user = models.User{
Email: data["email"],
Password: data["password"],
}
token := utils.GenerateNewAccessToken(string(user.ID))
// return response
return utils.SuccessJSON(c, fiber.StatusOK, "OK!", models.LoginResult{
UserInfo: user,
Token: token,
})
}
In utils folder:
package utils
func GenerateNewAccessToken(userId string) string {
secret := os.Getenv("JWT_SECRET_KEY")
minutesCount, _ := strconv.Atoi(os.Getenv("JWT_SECRET_KEY_EXPIRE_MINUTES_COUNT"))
token := jwt.New(jwt.SigningMethodHS256)
claims := token.Claims.(jwt.MapClaims)
claims["sub"] = userId // here just set id of user
claims["exp"] = time.Now().Add(time.Minute * time.Duration(minutesCount)).Unix()
t, _ := token.SignedString([]byte(secret))
return t
}
func GetUserID(c *fiber.Ctx) string {
user := c.Locals("jwt").(*jwt.Token)
claims := user.Claims.(jwt.MapClaims)
id := claims["sub"].(string)
return id
}
I have middleware called jwt_middleware
contains:
func JWTProtected() func(*fiber.Ctx) error {
config := jwtMiddleware.Config{
SigningKey: []byte(os.Getenv("JWT_SECRET_KEY")),
ContextKey: "jwt", // used in private routes
ErrorHandler: jwtError,
}
return jwtMiddleware.New(config)
}
func jwtError(c *fiber.Ctx, err error) error {
if err.Error() == "Missing or malformed JWT" {
return c.Status(fiber.StatusUnauthorized).JSON(fiber.Map{"message": "Authorization"})
}
}
route of userProfile:
auth := api.Group("/api/user")
auth.Get("/", middlewares.JWTProtected(), userControllers.UserInfo)
In profile userController:
func UserInfo(c *fiber.Ctx) error {
var user models.User
database.DB.Where("id = ?", utils.GetUserID).First(&user)
return utils.SuccessJSON(c, fiber.StatusOK, "user info!", user)
}
When I visit the route of user info with putting the token in the header I got this error in the terminal:
.../ProfileController.go:13 cannot convert 0x1567ea0 to Int8
[6.251ms] [rows:0] SELECT * FROM "users" WHERE id = '0x1567ea0' ORDER BY "users"."id" LIMIT 1
How can I get the id from token!
Hi, I need to get the user info from inside the Claims map from them JWT token. So far I got the contents of the Ctx.Local("user"), but when I try to access the Claims map, I get the following message: Claims undefined (type interface {} is interface with no methods)
.
I'm still pretty new on Golang, so I tried to convert it to a map[int]string, but has got no success. Can anyone help me?
Hello,
I'm trying to do something similar to #103, extract a JWT from a custom header field.
{
"X-Auth": "eyJ....."
}
I believe currently, it's impossible to achieve this, because an empty AuthScheme
value gets interpreted as default and set to "Bearer":
if cfg.AuthScheme == "" {
cfg.AuthScheme = "Bearer"
}
Perhaps we can default AuthScheme
to "Bearer" if AuthScheme == "" && TokenLookup == defaultTokenLookup
.
Please let me know what you think about this. I would be happy to make a PR.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.