简体   繁体   中英

How to enable CORS in Go

I'm new to this CORS stuff in golang. I use this package "github.com/rs/cors". I tested it with the example code:

package main

import (
    "log"
    "net/http"

    "github.com/julienschmidt/httprouter"
    "github.com/rs/cors"
)

func Hello(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
    w.Header().Set("Content-Type", "application/json")
    w.Write([]byte("{\"hello\": \"world\"}"))
}

func main() {
    router := httprouter.New()
    router.GET("/", Hello)

    _cors := cors.Options{
        AllowedMethods: []string{"POST", "OPTIONS"},
        AllowedOrigins: []string{"http://localhost:8080"},
    }
    handler := cors.New(_cors).Handler(router)

    http.ListenAndServe(":8282", handler)
}

When I hit from the browser, it responses normally without any issue. When I hit from client made in Go, same thing happen. What do I miss?

Edit: I expect that this CORS will filter request coming from different origin/server. When I put the allowed method to POST and OPTIONS only, and I hit with GET from browser and client made in Go, should it be returning error since GET is not allowed?, How to work with this package?

In my projects i always use a handler to set CORS and works very well.

func CORS(next http.HandlerFunc) http.HandlerFunc {
  return func(w http.ResponseWriter, r *http.Request) {
    w.Header().Add("Access-Control-Allow-Origin", "*")
    w.Header().Add("Access-Control-Allow-Credentials", "true")
    w.Header().Add("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
    w.Header().Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")

    if r.Method == "OPTIONS" {
        http.Error(w, "No Content", http.StatusNoContent)
        return
    }

    next(w, r)
  }
}

In this code block you can see the headers setting permission for other sources, this can make your resources accessible from other domains.

A way to use this, if are you using the standard HTTP library, its like a middleware:

func mainHandler(w http.ResponseWriter, r *http.Request){ ... }

http.HandleFunc("/",
    CORS(mainHandler),
)

CORS is a mechanism to prevent a script(ie Javascript) running in browser coming from different origin(server) calling to a specific server. This specific server need to be careful of any script hitting itself because some malicious things or any authorization policy might applied. This specific server can create a middleware in its APIs to check an preflight request, a CORS request using OPTIONS method with some specific headers it carry.

Preflight request is a component of CORS model where this is part of CORS mechanism standarization applied to browsers. So the one who sent this preflight requests are browsers if any scripts executed via browser(do not mistaking it with hitting from browser address bar). This preflight request applied to APIs that usually execute requests like in Javascript you have XMLHttpRequest or Fetch APIs. Any kind of request with any method sent through these APIs will be preceded by separated request called "preflight" request using OPTIONS method bringing additional headers detailing the information of the caller. This preflight request will be handled by the destination server by checking its request headers and comparing with its CORS regulation applied. This Options will return the information of what method, origins(allowed origins), or any headers allowed based on its rule. Once this preflight request finish and get response with detailed of headers containing information of destination server cors policy. If the caller didn't violate anything based on that server cors policy, then the API/browser will make next request after that preflight request which is the actual request. Otherwise will return as cors error and actual request will never be made.

Calling from browser address bar wont have any effect since you're not executing any script(from browser) and the browser address bar is usually a GET method, not OPTIONS method, hence won't be treated as preflight request. If you call it from client made in other programming language(eg Go), then CORS mechanism not applied here, because like other said cors applied to the calling from scripts in browsers. If you want to filter request from client other than browser(eg Go) from different server then what you need is OAUTH mechanism or ACL(Access Control List) which are different and have nothing to do with this CORS stuff.

Relating to the package you referred, that package is to ease your work so you dont have to handle the additional headers and preflight request yourself, instead you can wrap your handlers inside the package.

More about CORS here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM