Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Enable CORS in Golang

Hi I'm implementing rest apis and for that I want to allow cross origin requests to be served.

What I am currently doing:

Go-server code on AWS:

func (c *UserController) Login(w http.ResponseWriter, r *http.Request, ctx *rack.Context) { w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") ... ... c.render.Json(w,rsp, http.StatusOK) return } 

Ajax code on localhost:

<script> $( document ).ready(function() {     console.log( "ready!" );     $.ajax({         url: 'http://ip:8080/login',         crossDomain: true, //set as a cross domain requests         withCredentials:false,         type: 'post',         success: function (data) {             alert("Data " + data);         },     }); }); 

I am getting the following error on browser console: XMLHttpRequest cannot load http://ip:8080/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8081' is therefore not allowed access. The response had HTTP status code 422.

I tried adding preflight options:

func corsRoute(app *app.App) { allowedHeaders := "Accept, Content-Type, Content-Length, Accept-Encoding, Authorization,X-CSRF-Token"  f := func(w http.ResponseWriter, r *http.Request) {     if origin := r.Header.Get("Origin"); origin != "" {         w.Header().Set("Access-Control-Allow-Origin", "*")         w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")         w.Header().Set("Access-Control-Allow-Headers", allowedHeaders)         w.Header().Set("Access-Control-Expose-Headers", "Authorization")     }     return } app.Router.Options("/*p", f, publicRouteConstraint) } 

But it is not working.

What can be done to fix it.

like image 755
Yash Srivastava Avatar asked Sep 15 '16 09:09

Yash Srivastava


People also ask

How do I enable CORS globally?

Scope Rules for [EnableCors] You can enable CORS per action, per controller, or globally for all Web API controllers in your application. To enable CORS for a single action, set the [EnableCors] attribute on the action method. The following example enables CORS for the GetItem method only.

How do I fix CORS header Access-Control allow Origin missing?

If the server is under your control, add the origin of the requesting site to the set of domains permitted access by adding it to the Access-Control-Allow-Origin header's value. You can also configure a site to allow any site to access it by using the * wildcard. You should only use this for public APIs.

What happens if you enable CORS?

Cross-origin resource sharing (CORS) is a mechanism implemented in web browsers to allow or deny requests coming from a different domain to your web app. With CORS, web browsers and web servers agree on a standard protocol to understand whether the resources are allowed to access or not.

When should you enable CORS?

Cross-origin resource sharing (CORS) is a browser security feature that restricts cross-origin HTTP requests that are initiated from scripts running in the browser. If your REST API's resources receive non-simple cross-origin HTTP requests, you need to enable CORS support.

What is Cors in Golang?

CORS in Golang. Dealing Ajax Cross Origin. CORS stands for Cross Origin Resource Sharing, and consists of a handshake of cryptic headers (usually) from a browser to a web api server. The handshake isn’t well known, and usually people just “enable” cors in the web server, and all is right with the world again.

What is cors and how does it work?

CORS stands for Cross Origin Resource Sharing, and consists of a handshake of cryptic headers (usually) from a browser to a web api server. The handshake isn’t well known, and usually people just “enable” cors in the web server, and all is right with the world again. Here is how the handshake breaks down:

What is a CORS header?

CORS stands for Cross Origin Resource Sharing, and consists of a handshake of cryptic headers (usually) from a browser to a web api server. The handshake isn’t well known, and usually people just “enable” cors in the web server, and all is right with the world again.

How to allow Cors for preflight request?

For allowing CORS your server should to catch all Preflight request that's browser sends before real query with OPTIONS method to the same path.


2 Answers

I use gorilla/mux package to build Go RESTful API server, and client use JavaScript Request can work,

My Go Server runs at localhost:9091, and the Server code:

router := mux.NewRouter() //api route is /people,  //Methods("GET", "OPTIONS") means it support GET, OPTIONS router.HandleFunc("/people", GetPeopleAPI).Methods("GET", "OPTIONS") log.Fatal(http.ListenAndServe(":9091", router)) 

I find giving OPTIONS here is important, otherwise error will occur:

OPTIONS http://localhost:9091/people 405 (Method Not Allowed)

Failed to load http://localhost:9091/people: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9092' is therefore not allowed access. The response had HTTP status code 405.

after allow OPTIONS it works great. I get the idea from This Article.

Besides, MDN CORS doc mention:

Additionally, for HTTP request methods that can cause side-effects on server's data, the specification mandates that browsers "preflight" the request, soliciting supported methods from the server with an HTTP OPTIONS request method, and then, upon "approval" from the server, sending the actual request with the actual HTTP request method.

Following is the api GetPeopleAPI method, note in the method I give comment //Allow CORS here By * or specific origin, I have another similar answer explaining the concept of CORS Here:

func GetPeopleAPI(w http.ResponseWriter, r *http.Request) {      //Allow CORS here By * or specific origin     w.Header().Set("Access-Control-Allow-Origin", "*")      w.Header().Set("Access-Control-Allow-Headers", "Content-Type")     // return "OKOK"     json.NewEncoder(w).Encode("OKOK") } 

In the client, I use html with javascript on localhost:9092, and javascript will send request to server from localhost:9092

function GetPeople() {     try {         var xhttp = new XMLHttpRequest();         xhttp.open("GET", "http://localhost:9091/people", false);         xhttp.setRequestHeader("Content-type", "text/html");         xhttp.send();         var response = JSON.parse(xhttp.response);         alert(xhttp.response);     } catch (error) {         alert(error.message);     } } 

and the request can successfully get response "OKOK" .

You can also check response/request header information by tools like Fiddler .

like image 97
yu yang Jian Avatar answered Oct 17 '22 08:10

yu yang Jian


Thanks for the clue - it's all in the header! I use only these golang headers on the server side:

w.Header().Set("Content-Type", "text/html; charset=utf-8") w.Header().Set("Access-Control-Allow-Origin", "*") 

Now works with this JQuery:

<script  src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"> </script> <script> $.ajax({     type: 'GET',     url: 'https://www.XXXXXXX.org/QueryUserID?u=juXXXXny&p=blXXXXXne',     crossDomain: true,     dataType: 'text',     success: function(responseData, textStatus, jqXHR) {         alert(responseData);             },     error: function (responseData, textStatus, errorThrown) {         alert('POST failed.');     } }); </script> 
like image 23
user2099484 Avatar answered Oct 17 '22 07:10

user2099484