Git Product home page Git Product logo

jwt's Introduction

⚠️ Deprecated repository

This middleware is no longer maintained, it is available within Fiber Contrib.

jwt's People

Contributors

418coffee avatar amaury-tobias avatar codemicro avatar dennybiasiolli avatar dependabot[bot] avatar efectn avatar fenny avatar github-actions[bot] avatar gmlewis avatar gohryt avatar hi019 avatar huybuidev avatar inirudi avatar jereth avatar kiyonlin avatar lawzava avatar micahparks avatar renewerner87 avatar shytikov avatar svs-valiton avatar thomasvvugt avatar vmantese avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

jwt's Issues

Did this middleware support JWKS?

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?

Seems expiration is not checked

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.

Discuss naming

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.

Empty AuthScheme not possible for headers

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.

Request to release v0.0.6

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.

Request to release v0.0.3

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.

readme: `token` is used before it was created

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)

Allow Header Extraction without AuthScheme

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:

jwt/jwt.go

Line 39 in 1a9806c

return auth[l+1:], nil

Suggestion: Either we check if AuthScheme is empty or we trim the token and do not crop with +1

How to control the format which a value is parsed during foo.Claims.(jwt.MapClaims)?

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?

how to handle optional auth route

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

We should not silently put JWT to ctx.Locals()

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.

Update keyfunc

There have been some improvements to github.com/MicahParks/keyfunc since this project first supported JWT verification from JWK Sets.

Two notable ones are:

  1. github.com/MicahParks/keyfunc only imports github.com/golang-jwt/jwt now.
  2. The key type for parsing is now based on the JWK Set's 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.

  • This project's 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.
  • There could be a data race condition with the 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.)

Get Claims data from JWT

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?

Nil pointer dereference on KeyRefreshUnknownKID

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 {

how to get username, user id from claims when working in handlers?

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!

Jwt middleware always return 400 Bad Request error while working with websocket middleware

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?

Multimple Extractors

Its possible to use multiple extractors by example from cookie and Header at the same time

cannot convert 0x1567ea0 to Int8

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!

work with wildcard routing ?

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!

How is expiration handled?

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?

Jwt middleware not using fiber ErrorHandler

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 😅

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.