fiber icon indicating copy to clipboard operation
fiber copied to clipboard

🤗 [Question]: How to skip a handler function if the auth middleware fails and directly skip to response handler?

Open balanikaran opened this issue 1 year ago • 5 comments

Question Description

I'm having the code structure like this below:

someRouter.Use(auth.SomeAuthMiddleware)

someRouter.Post(
	"/someEndpoint",
	controller.SomeEndpointHandler,
	genericResponseHandler.GenericJSONResponseHandler,
)

What I want is, if my Auth Middleware fails for some reason, my SomeEndpointHandler should not run, and it should directly skip to the GenericJSONResponseHandler with the set status code.

Is that even possible? Or is my approach of code design is correct or not?

Code Snippet (optional)

No response

Checklist:

  • [X] I agree to follow Fiber's Code of Conduct.
  • [X] I have checked for existing issues that describe my questions prior to opening this one.
  • [X] I understand that improperly formatted questions may be closed without explanation.

balanikaran avatar Aug 09 '22 06:08 balanikaran

Thanks for opening your first issue here! 🎉 Be sure to follow the issue template! If you need help or want to chat with us, join us on Discord https://gofiber.io/discord

welcome[bot] avatar Aug 09 '22 06:08 welcome[bot]

fail with "panic" or error?

if you want your handlers to continue, you would have to catch these errors, react to them and ignore them in the flow and put some information in the locals(https://docs.gofiber.io/api/ctx#locals) that you can use later for skipping

ReneWerner87 avatar Aug 09 '22 06:08 ReneWerner87

Yeah, I'm just setting the relevant status_code in the locals and then skipping the handlers by checking in the very beginning of the following handlers. I just wanted to know if there is any short-circuiting kind of pattern available.

balanikaran avatar Aug 09 '22 06:08 balanikaran

I just wanted to know if there is any short-circuiting kind of pattern available. no i think not @efectn @Trim21 any other ideas ?

ReneWerner87 avatar Aug 09 '22 09:08 ReneWerner87

So if I understand correctly, you want GenericJSONResponseHandler to be executed but not SomeEndpointHandler when SomeAuthMiddleware failed to authorized current request.

Common case for this is to just response (or return a error) in the SomeAuthMiddleware and don't' call c.Next(), so the middleware and handler after this middleware won't be executed by nature.

Guessing from your handler name, the GenericJSONResponseHandler is used to create final response,

You can use a middleware GenericJSONResponseMiddleware and add it before auth middleware, use a customized error, return it in your auth middleware and use errors.As to check if the error is expected error type.

would look like this:

type myError struct {
	Code     int
	Message  string
	Response any
}

func (e myError) Error() string {
	return e.Message
}

func GenericJSONResponseHandler(c *fiber.Ctx) error {
	err := c.Next()

	var ef myError
	if errors.As(err, &ef) {
		return c.Status(ef.Code).JSON(ef.Response)
	}

	return err
}

var logined bool

func SomeAuthMiddleware(c *fiber.Ctx) error {
	if !logined {
		return myError{
			Code:     http.StatusUnauthorized,
			Message:  "",
			Response: fiber.Map{"err": "not login"},
		}
	}

	return c.Next()
}

trim21 avatar Aug 09 '22 16:08 trim21

Hey, thanks for the solution here, let me evaluate if we can use it in our code.

This was really helpful. :)

balanikaran avatar Aug 11 '22 10:08 balanikaran

If you have some questions more, feel free to reopen the issue.

efectn avatar Aug 11 '22 12:08 efectn