GoFiber different middleware for groups that share the same base route

171 Views Asked by At
func GetRouter() *fiber.App {
    app := fiber.New()

    public_group := app.Group("/")
    public_group.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World !")
    })

    public_group.Post("/register", handlers.RegisterUser)
    public_group.Post("/login", handlers.AuthenticateUser)
        ...

    auth_group := app.Group("/", middleware.AuthRequired)
    auth_group.Get("/auth/me", handlers.GetUser)
    auth_group.Put("/auth/me", handlers.UpdateUser)
    auth_group.Post("/auth/me/password", handlers.UpdatePassword)
...

The code should've conveyed the point, but again, i have some public routes and some routes where I want to enforce the auth middleware. Right now, when I try to access the / route, expecting a "hello world" response, I get this instead: (logged by the server)

auth middleware engaged
[ 2023-12-18 16:22:41 ] GET /v0 | 127.0.0.1 - ✗ Authorization header does not exist
Response: 200 [took 337.709µs]
{
  "message": "authorization header required to access this endpoint",
  "status": 401
}

The auth middleware should never have been engaged here in the first place! Here's the auth middleware if it helps:

package middleware

import (
    responses "backend/models/api/responses"
    "backend/utils"
    "fmt"

    fiber "github.com/gofiber/fiber/v2"
)

func AuthRequired(c *fiber.Ctx) error {
    fmt.Println("auth middleware engaged")
    auth_header := c.Get("Authorization")
    if auth_header == "" {
        return c.JSON(responses.BaseResponse{
            Status:  401,
            Message: "authorization header required to access this endpoint",
        })
    }
    if _, err := utils.ValidateJWT(auth_header); err != nil {
        return c.JSON(responses.BaseResponse{
            Status:  401,
            Message: "invalid authorization header",
        })
    }
    return c.Next()
}

Also, the present code is inspired by this answer to a similar query

I don't want to be using different base routes. Presently, this fixes the issue, but I would still like to find out how to do what I originally wanted

    app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World !")
    })

    app.Post("/auth/register", handlers.RegisterUser)
    app.Post("/auth/login", handlers.AuthenticateUser)

    accounts_route := app.Group("/accounts", middleware.AuthRequired)

    accounts_route.Get("/me", handlers.GetUser)
    accounts_route.Put("/me", handlers.UpdateUser)
    accounts_route.Post("/me/password", handlers.UpdatePassword)
    ...
1

There are 1 best solutions below

1
levniko On

You are effectively applying the middleware.AuthRequired middleware to the root path ("/"), which includes all routes defined after this line. This means that the middleware is being applied to your public routes as well, hence the unexpected authentication requirement for the "/" route. You can try this:

auth_group := app.Group("/auth", middleware.AuthRequired)