Echo CORS с промежуточным ПО Proxy вызывает проблемы с заголовком ответа Access-Allow-Origins - PullRequest
0 голосов
/ 09 октября 2019

Я использую LabStack Golang Echo Framework для создания службы.

Один из маршрутов, необходимо прокси-запросы и ответы к и от серверной службы.

Но я такжеМне нужен CORS для работы с этим сервисом.

Так что я использую middleware.CORSWithConfig вместе с middleware.ProxyWithConfig в моем стеке запросов / ответов.

Я вижу некоторую странностьс заголовком Access-Control-Allow-Origins, где значение этого заголовка в ответе от прокси-службы на мой Echo-сервер *, но как только оно проходит через прокси, оно меняется на *, * к тому времени, когда возвращается вклиент. После чего я начинаю видеть следующие ошибки браузера, связанные с нарушениями CORS:

VM1627:362 Access to XMLHttpRequest at 'http://localhost:6273/' from origin 'http://localhost:8002' has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values '*, *', but only one is allowed.

Кто-нибудь сталкивался с этим? У кого-нибудь есть идеи, почему это может происходить, и, возможно, как это обойти?

Вот пример кода:

package main

func singleTargetBalancer(url *url.URL) middleware.ProxyBalancer {
    targetURL := []*middleware.ProxyTarget{
        {
            URL: url,
        },
    }
    return middleware.NewRoundRobinBalancer(targetURL)
}

func Noop(ctx echo.Context) (err error) {
    ctx.String(
        http.StatusNotImplemented,
        "No op handler should never be reached!",
    )

    return err
}

func main() {
        e := echo.New()
    e.HideBanner = true
    e.Use(
        middleware.CORSWithConfig(middlewares.CustomCorsConfig),
        middlewares.ThriftMetrics(),
    )

        // Have to use a Noop handler since we're not trying to set up a full-on proxy for the backend service.  We only want this one route to be proxied.
        e.POST(
        "/",
        handlers.Noop,
        middleware.ProxyWithConfig(middleware.ProxyConfig{
             Balancer: singleTargetBalancer("[backend service URL]"),
            })
    )
}

1 Ответ

0 голосов
/ 11 октября 2019

В конечном итоге я решил эту проблему, написав специальное промежуточное ПО Echo, чтобы подключиться к ответу до того, как промежуточное ПО прокси-сервера Echo сможет отправить заголовки обратно клиенту.

func setResponseACAOHeaderFromRequest (req http.Request, resp echo.Response) {
    resp.Header().Set(echo.HeaderAccessControlAllowOrigin, 
    req.Header.Get(echo.HeaderOrigin))
}

func ACAOHeaderOverwriteMiddleware(next echo.HandlerFunc) echo.HandlerFunc {
    return func(ctx echo.Context) error {
        ctx.Response().Before(func() {
            setResponseACAOHeaderFromRequest(*ctx.Request(), *ctx.Response())
        })
        return next(ctx)
    }
}

Затем просто поместите это промежуточное ПО в e.Use() вправо до вашего промежуточного ПО для прокси:

e.POST(
        "/",
        handlers.Noop,
        ACAOHeaderOverwriteMiddleware,
        middleware.ProxyWithConfig(middleware.ProxyConfig{
             Balancer: singleTargetBalancer("[backend service URL]"),
        })
)

Документы для Echo's Request::Before() hook: https://echo.labstack.com/guide/response#before-response

...