How to Grouping Endpoint by Middleware in Go Fiber?

71 Views Asked by At

I'm encountering an issue with route setup in Go using Fiber.

app := fiber.New()

    app.Get("/", func(c *fiber.Ctx) error {
        return c.SendString("Hello, World!")
    })
    basicAuth1 := basicauth.New(basicauth.Config{
        Users: map[string]string{
            "go": "123",
        },
        Unauthorized: func(ctx *fiber.Ctx) error {
            return fiber.NewError(fiber.StatusForbidden, "Error BasicAuth V1")
        },
    })
    basicAuth2 := basicauth.New(basicauth.Config{
        Users: map[string]string{
            "go": "321",
        },
        Unauthorized: func(ctx *fiber.Ctx) error {
            return fiber.NewError(fiber.StatusForbidden, "Error BasicAuth V2")
        },
    })
    base := app.Group("/api")
    v1 := base.Group("/", basicAuth1)
    v1.Get("/v1", func(ctx *fiber.Ctx) error {
        return ctx.SendString("a from v1")
    })

    v2 := base.Group("/", basicAuth2)
    v2.Get("/v2", func(ctx *fiber.Ctx) error {
        return ctx.SendString("a from v2")
    })

    app.Listen(":3000")

When I attempt to access the api/v2 endpoint, I receive an error from the basicAuth1 middleware. This middleware should only be applied to a different group and not affect api/v2. I didn't experience this issue with similar middleware usage and group configuration in Echo. and I just want grouping handler by middleware.

api/v1 with correct auth

api/v2 with correct auth

Grouping endpoint by its Middleware

1

There are 1 best solutions below

2
sk shahriar ahmed raka On

In your code, you're experiencing this issue because you're attaching both basicAuth1 and basicAuth2 to the same base group (base). When you define v1 and v2 groups, you're attaching the respective basic auth middleware to them, but you're not removing or overriding the middleware from the parent group (base).

To resolve this issue you can structure code like this:

package main

import (
    "github.com/gofiber/fiber/v2"
    "github.com/gofiber/fiber/v2/middleware/basicauth"
)

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

    base := app.Group("/api")

    v1 := base.Group("/v1", basicauth.New(basicauth.Config{
        Users: map[string]string{
            "go": "123",
        },
        Unauthorized: func(ctx *fiber.Ctx) error {
            return fiber.NewError(fiber.StatusForbidden, "Error BasicAuth V1")
        },
    }))
    v1.Get("/", func(ctx *fiber.Ctx) error {
        return ctx.SendString("a from v1")
    })

    v2 := base.Group("/v2", basicauth.New(basicauth.Config{
        Users: map[string]string{
            "go": "321",
        },
        Unauthorized: func(ctx *fiber.Ctx) error {
            return fiber.NewError(fiber.StatusForbidden, "Error BasicAuth V2")
        },
    }))
    v2.Get("/", func(ctx *fiber.Ctx) error {
        return ctx.SendString("a from v2")
    })

    app.Listen(":3000")
}

I have attached the basicauth middleware directly to each sub-group (v1 and v2) rather than attaching it to the base group (base). This way, each group has its own middleware configuration, and endpoints within those groups will only be affected by the middleware attached to their specific group.

Testing /api/v1 endpoint:

curl -X GET http://localhost:3000/api/v1 -u go:123

Testing /api/v2 endpoint:

curl -X GET http://localhost:3000/api/v2 -u go:321