1

考虑以下示例,该示例将基本身份验证中间件用于自定义组,并且还使用自定义 http 错误处理程序:

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"))
}

如果我省略e.HTTPErrorHandler = customHTTPErrorHandler,那么基本身份验证中间件会在所有现代浏览器中触发提示。一旦我使用自定义错误处理程序,我总是会在没有提示的情况下遇到 401。

我知道

当基本身份验证中间件发现无效凭据时,它返回 401 - 未经授权的错误,中止当前的 HTTP 请求。

如文档https://echo.labstack.com/guide/error-handling中所述。

在这种情况下,如何让提示再次起作用?我应该编写一个自定义的基本身份验证中间件吗?我将如何在其中包含基本的身份验证提示?

我也尝试在顶部使用or , c.Request().BasicAuth()但它也不会触发提示。c.Response().Header().Add(echo.HeaderWWWAuthenticate, `Basic realm="mydomain"`)e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { return func(c echo.Context) error {}})

卷曲请求但是给了我预期的结果:

curl http://localhost:1325/admin
401
curl -u test:test http://localhost:1325/admin
Admin

但是,如果我在浏览器中打开以下 url,http://test:test@localhost:1325/admin我会在没有基本身份验证提示的情况下遇到相同的错误(401 Unauthorized)。

4

1 回答 1

1

构造错误的方法应该如下所示。刚刚显示错误构造以缩小范围,需要执行额外检查

func customHTTPErrorHandler(err error, c echo.Context) {

    msg := echo.Map{"message": "Unauthorized"}

    err = c.JSON(401, msg)
}

您已将 http 状态代码设置为http.StatusOK. 下线。

if err := c.String(http.StatusOK, strconv.Itoa(code)); err != nil {

应该是401http.StatusUnauthorized

if err := c.String(http.StatusUnauthorized, strconv.Itoa(code)); err != nil {
        c.Logger().Error(err)
    }
于 2020-12-14T18:48:00.200 回答