Skip to content
This repository has been archived by the owner on May 24, 2023. It is now read-only.

work with wildcard routing ? #59

Closed
Macrow opened this issue Sep 19, 2021 · 5 comments
Closed

work with wildcard routing ? #59

Macrow opened this issue Sep 19, 2021 · 5 comments

Comments

@Macrow
Copy link

Macrow commented Sep 19, 2021

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!

@shytikov
Copy link
Contributor

Could you maybe provide a code snippet to illustrate the problem?

@Macrow
Copy link
Author

Macrow commented Sep 20, 2021

func main() {
	app := fiber.New()

	// Login route
	app.Post("/login", login)

	// Unauthenticated route
	app.Get("/", accessible)

	// JWT Middleware
	app.Use(jwtware.New(jwtware.Config{
		SigningKey: []byte("secret"),
	}))

	// Restricted Routes
	app.Get("/restricted", restricted)

	// handle not found error (https: //docs.gofiber.io/extra/faq#how-do-i-handle-custom-404-responses)
	app.Use(func(c *fiber.Ctx) error {
		return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!")
	})

	app.Listen(":3000")
}

In this code snippet, if we visit some url(not exist) without jwt token, we can't reach not found handler.

according to gofiber/fiber#207 , we just could handle like this

func main() {
	app := fiber.New()

	// Login route
	app.Post("/login", login)

	// Unauthenticated route
	app.Get("/", accessible)

	// JWT Middleware <- we could not use this middleware
	//app.Use(jwtware.New(jwtware.Config{
	//	SigningKey: []byte("secret"),
	//}))

	// Restricted Routes
	app.Get("/restricted", jwtHandler, restricted)

	// handle not found error (https: //docs.gofiber.io/extra/faq#how-do-i-handle-custom-404-responses)
	app.Use(func(c *fiber.Ctx) error {
		return c.Status(fiber.StatusNotFound).SendString("Sorry can't find that!")
	})

	app.Listen(":3000")
}

func JwtHandler(c *fiber.Ctx) error {
	// retrieve raw token
	// parse raw token
	// store custom claims
	// store custom info into fiber.Locals
	// some authorization checking by casbin for example
	return c.Next()
}

@shytikov
Copy link
Contributor

Not sure I'm getting information from gofiber/fiber#207 right, so maybe @ReneWerner87 could correct me there, but for me that looks like desired behavior – seems to be that all auth middleware work this way in fiber – people won't be able to discover the structure of the website (or an API) if they would try to.

But I believe it could be some workarounds for that:

  • Add auth middleware before specific route, like here: 🤔 Middleware seems to run earlier than wildcard routing fiber#207 (comment);
  • If there are too many routes, maybe it would be possible to group them and add auth middleware to selected groups only;
  • If it's still undesired, you may try to override ErrorHandler in the configuration of this middleware, so instead of sending 401 in case of missing token it would let the execution path through. And you could check the presence of a token in ctx.Locals() map. And in case if it is missing you may send 401 from your handler instead.

But please don't take my words as the final truth, I'm not the top banana here :)

@Macrow
Copy link
Author

Macrow commented Sep 20, 2021

@shytikov Thanks for your reply, you are great! :)

Here is my solution for now

method.go

func assembleHandler(handler ...fiber.Handler) []fiber.Handler {
	h := make([]fiber.Handler, 0, len(handler) + 1)
	h = append(h, auth.JwtHandler)
	h = append(h, handler...)
	return h
}

func AuthGet(router fiber.Router, path string, handler ...fiber.Handler) fiber.Router {
	return router.Get(path, assembleHandler(handler...)...)
}

func AuthPost(router fiber.Router, path string, handler ...fiber.Handler) fiber.Router {
	return router.Post(path, assembleHandler(handler...)...)
}

func AuthPut(router fiber.Router, path string, handler ...fiber.Handler) fiber.Router {
	return router.Put(path, assembleHandler(handler...)...)
}

func AuthPatch(router fiber.Router, path string, handler ...fiber.Handler) fiber.Router {
	return router.Patch(path, assembleHandler(handler...)...)
}

func AuthDelete(router fiber.Router, path string, handler ...fiber.Handler) fiber.Router {
	return router.Delete(path, assembleHandler(handler...)...)
}

route.go

func Routes(app *fiber.App) {
        // not handle auth
        app.Get("/your-path", v1.SomeService)
        
        // v1
        apiV1 := app.Group("/api/v1")
        
        // auth
        auth := apiV1.Group("auth")
        // handle auth
        AuthPost(auth, "/login", v1.Login)
}

There should be a better way.

@gaby
Copy link
Member

gaby commented Apr 11, 2023

@ReneWerner87 This is from v1, can it be closed?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants