IT박스

HTTP 헤더 설정

itboxs 2020. 6. 6. 08:59
반응형

HTTP 헤더 설정


Go 웹 서버에서 헤더를 설정하려고합니다. 패키지를 사용 gorilla/mux하고 net/http있습니다.

Access-Control-Allow-Origin: *도메인 간 AJAX를 허용하도록 설정하고 싶습니다 .

내 Go 코드는 다음과 같습니다.

func saveHandler(w http.ResponseWriter, r *http.Request) {
// do some stuff with the request data
}

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/save", saveHandler)
    http.Handle("/", r)
    http.ListenAndServe(":"+port, nil)
}

net/http내가 어떻게 설정 응답 헤더에 정확히 모르겠어요 - 패키지는 클라이언트 인 것처럼 HTTP 요청 헤더를 보내는 기술 문서를 가지고?


신경 쓰지 마, 알아 냈어-나는 Set()방법을 사용했다 Header().

내 핸들러는 이제 다음과 같습니다.

func saveHandler(w http.ResponseWriter, r *http.Request) {
    // allow cross domain AJAX requests
    w.Header().Set("Access-Control-Allow-Origin", "*")
}

어쩌면 이것은 때때로 나 자신처럼 박탈당한 카페인으로 누군가를 도울 것입니다 :)


위의 모든 답변은 OPTIONS 사전 비행 요청을 처리하지 못하기 때문에 잘못되었습니다. 해결책은 mux 라우터의 인터페이스를 재정의하는 것입니다. 커스텀 헤더로 실패한 AngularJS $ http get 요청을 참조하십시오 (CORS로 제공).

func main() {
    r := mux.NewRouter()
    r.HandleFunc("/save", saveHandler)
    http.Handle("/", &MyServer{r})
    http.ListenAndServe(":8080", nil);

}

type MyServer struct {
    r *mux.Router
}

func (s *MyServer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
    if origin := req.Header.Get("Origin"); origin != "" {
        rw.Header().Set("Access-Control-Allow-Origin", origin)
        rw.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        rw.Header().Set("Access-Control-Allow-Headers",
            "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
    }
    // Stop here if its Preflighted OPTIONS request
    if req.Method == "OPTIONS" {
        return
    }
    // Lets Gorilla work
    s.r.ServeHTTP(rw, req)
}

완전히 공개적인 행동이 필요할 때까지 Origin에 '*'를 사용하지 마십시오. Wikipedia는 다음과
같이 말합니다 .

"*"의 값은 HTTP 인증, 클라이언트 측 SSL 인증서 또는 쿠키 전송을 의미하는 요청이 자격 증명을 제공 할 수 없다는 점에서 특별합니다. "

즉, 간단한 인증과 같은 구현을 시도 할 때 특히 Chrome에서 많은 오류가 발생합니다.

올바른 래퍼는 다음과 같습니다.

// Code has not been tested.
func addDefaultHeaders(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        if origin := r.Header.Get("Origin"); origin != "" {
            w.Header().Set("Access-Control-Allow-Origin", origin)
        }
        w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token")
        w.Header().Set("Access-Control-Allow-Credentials", "true")
        fn(w, r)
    }
}

프리 플라이트 OPTIONS 요청에이 헤더를 모두 회신하는 것을 잊지 마십시오.


적절한 golang 미들웨어를 설정하여 모든 엔드 포인트에서 재사용 할 수 있습니다.

도우미 유형 및 기능

type Adapter func(http.Handler) http.Handler
// Adapt h with all specified adapters.
func Adapt(h http.Handler, adapters ...Adapter) http.Handler {
    for _, adapter := range adapters {
        h = adapter(h)
    }
    return h
}

실제 미들웨어

func EnableCORS() Adapter {
    return func(h http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

            if origin := r.Header.Get("Origin"); origin != "" {
                w.Header().Set("Access-Control-Allow-Origin", origin)
                w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
                w.Header().Set("Access-Control-Allow-Headers",
                    "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
            }
            // Stop here if its Preflighted OPTIONS request
            if r.Method == "OPTIONS" {
                return
            }
            h.ServeHTTP(w, r)
        })
    }
}

엔드 포인트

기억하세요! 미들웨어가 역순으로 적용됩니다 (ExpectGET ()이 먼저 실행 됨)

mux.Handle("/watcher/{action}/{device}",Adapt(api.SerialHandler(mux),
    api.EnableCORS(),
    api.ExpectGET(),
))

이 경우 래퍼를 만듭니다.

func addDefaultHeaders(fn http.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        fn(w, r)
    }
}

If you don't want to override your router (if you don't have your app configured in a way that supports this, or want to configure CORS on a route by route basis), add an OPTIONS handler to handle the pre flight request.

Ie, with Gorilla Mux your routes would look like:

accounts := router.Path("/accounts").Subrouter()
accounts.Methods("POST").Handler(AccountsCreate)
accounts.Methods("OPTIONS").Handler(AccountsCreatePreFlight)

Note above that in addition to our POST handler, we're defining a specific OPTIONS method handler.

And then to actual handle the OPTIONS preflight method, you could define AccountsCreatePreFlight like so:

// Check the origin is valid.
origin := r.Header.Get("Origin")
validOrigin, err := validateOrigin(origin)
if err != nil {
    return err
}

// If it is, allow CORS.
if validOrigin {
    w.Header().Set("Access-Control-Allow-Origin", origin)
    w.Header().Set("Access-Control-Allow-Methods", "POST")
    w.Header().Set("Access-Control-Allow-Headers",
        "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
}

What really made this all click for me (in addition to actually understanding how CORS works) is that the HTTP Method of a preflight request is different from the HTTP Method of the actual request. To initiate CORS, the browser sends a preflight request with HTTP Method OPTIONS, which you have to handle explicitly in your router, and then, if it receives the appropriate response "Access-Control-Allow-Origin": origin (or "*" for all) from your application, it initiates the actual request.

I also believe that you can only do "*" for standard types of requests (ie: GET), but for others you'll have to explicitly set the origin like I do above.


I had the same issue as described above the solutions given above are correct, the set up I have is as follows 1) Angularjs for the Client 2) Beego framework for GO server

Please following these points 1) CORS settings must be enabled only on GO server 2) Do NOT add any type of headers in angularJS except for this

.config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.useXDomain = true;
        delete $httpProvider.defaults.headers.common['X-Requested-With'];
    }])

In you GO server add the CORS settings before the request starts to get processed so that the preflight request receives a 200 OK after which the the OPTIONS method will get converted to GET,POST,PUT or what ever is your request type.


I know this is a different twist on the answer, but isn't this more of a concern for a web server? For example, nginx, could help.

The ngx_http_headers_module module allows adding the “Expires” and “Cache-Control” header fields, and arbitrary fields, to a response header

...

location ~ ^<REGXP MATCHING CORS ROUTES> {
    add_header Access-Control-Allow-Methods POST
    ...
}
...

Adding nginx in front of your go service in production seems wise. It provides a lot more feature for authorizing, logging,and modifying requests. Also, it gives the ability to control who has access to your service and not only that but one can specify different behavior for specific locations in your app, as demonstrated above.

I could go on about why to use a web server with your go api, but I think that's a topic for another discussion.

참고URL : https://stackoverflow.com/questions/12830095/setting-http-headers

반응형