Consider the following example which utilizes the basic auth middleware for a custom group and also uses a custom http error handler:
package main
import (
"net/http"
"strconv"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
// customHTTPErrorHandler utilizies custom error pages in public/error
func customHTTPErrorHandler(err error, c echo.Context) {
code := http.StatusInternalServerError
if he, ok := err.(*echo.HTTPError); ok {
code = he.Code
}
if err := c.String(http.StatusOK, strconv.Itoa(code)); err != nil {
c.Logger().Error(err)
}
}
func main() {
e := echo.New()
e.HTTPErrorHandler = customHTTPErrorHandler
e.Use(middleware.Logger())
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Index\n")
})
g := e.Group("/admin", middleware.BasicAuth(func(u, p string, c echo.Context) (bool, error) {
if u == "test" && p == "test" {
return true, nil
}
return false, nil
}))
g.GET("", func(c echo.Context) error {
return c.String(http.StatusOK, "Admin\n")
})
e.Logger.Fatal(e.Start("localhost:1325"))
}
If I omit e.HTTPErrorHandler = customHTTPErrorHandler
then the basic auth middleware triggers the prompt in all modern browsers. As soon as I use the custom error handler I always run into 401 without a prompt.
I know that
when basic auth middleware finds invalid credentials it returns 401 - Unauthorized error, aborting the current HTTP request.
as stated in the docs https://echo.labstack.com/guide/error-handling.
How do I get the prompt working again in this case? Am I supposed to write a custom basic auth middleware? How would I include the basic auth prompt there?
I also tried to use c.Request().BasicAuth()
or c.Response().Header().Add(echo.HeaderWWWAuthenticate, `Basic realm="mydomain"`)
within a
e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error {}})
on top but it doesn't trigger the prompt neither.
Curl requests however giving me the expected results:
curl http://localhost:1325/admin
401
curl -u test:test http://localhost:1325/admin
Admin
But if I open up the following url in a browser http://test:test@localhost:1325/admin
I run into the same error (401 Unauthorized) without the basic auth prompt.
The way is construct the error should be as below I guess. Just shown err construction to narrow down, need to perform additional checks
func customHTTPErrorHandler(err error, c echo.Context) {
msg := echo.Map{"message": "Unauthorized"}
err = c.JSON(401, msg)
}
You have set http status code as http.StatusOK
. Below line.
if err := c.String(http.StatusOK, strconv.Itoa(code)); err != nil {
It should be 401 http.StatusUnauthorized
if err := c.String(http.StatusUnauthorized, strconv.Itoa(code)); err != nil {
c.Logger().Error(err)
}