3

I'm trying to build an API using gorilla mux and google cloud endpoints but am having trouble getting it to allow cross origin requests. I'm using the following code in my web application to send the requests:

$.ajax("https://my.api/echo", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
        "Authorization": "Bearer " + localStorage.id_token
    },
    data: JSON.stringify({
        "message": this.query
    })
}).done(function(response) {
    console.log(response);
});

and am getting the following errors in my browser's console:

OPTIONS https://my.api/echo 403 ()

Failed to load https://my.api/echo: Response to preflight request
doesn't pass access control check: No 'Access-Control-Allow-Origin'
header is present on the requested resource. Origin 
'http://127.0.0.1:8081' is therefore not allowed access. The response
had HTTP status code 403.

The code for endpoint is:

func main() {
    r := mux.NewRouter()

    r.HandleFunc("/echo", echoHandler).Methods("POST", "OPTIONS")
    headers := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type"})
    origins := handlers.AllowedOrigins([]string{"*"})
    methods := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"})

    http.Handle("/", r)

    port := 10080
    if portStr := os.Getenv("PORT"); portStr != "" {
        port, _ = strconv.Atoi(portStr)
    }
    log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), handlers.CORS(headers, origins, methods)(r)))
}

func echoHandler(w http.ResponseWriter, r *http.Request) {
    // echoHandler reads a JSON object from the body, and writes it back out.
    var msg interface{}
    if err := json.NewDecoder(r.Body).Decode(&msg); err != nil {
        if _, ok := err.(*json.SyntaxError); ok {
            errorf(w, http.StatusBadRequest, "Body was not valid JSON: %v", err)
            return
        }
        errorf(w, http.StatusInternalServerError, "Could not get body: %v", err)
        return
    }

    b, err := json.Marshal(msg)
    if err != nil {
        errorf(w, http.StatusInternalServerError, "Could not marshal JSON: %v", err)
        return
    }
    w.Write(b)
}

My app.yaml is:

# [START swagger]
swagger: "2.0"
info:
  description: "My API"
  title: "My API"
  version: "1.0.0"
host: "my.api"
x-google-endpoints:
  - name: "my.api"
    target: "X.X.X.X"
    allowCors: "true"
# [END swagger]
basePath: "/"
consumes:
- "application/json"
produces:
- "application/json"
schemes:
- "https"
paths:
  "/echo":
    post:
      description: "Echo back a given message."
      operationId: "echo"
      produces:
      - "application/json"
      responses:
        200:
          description: "Echo"
          schema:
            $ref: "#/definitions/echoMessage"
      parameters:
      - description: "Message to echo"
        in: body
        name: message
        required: true
        schema:
          $ref: "#/definitions/echoMessage"   
definitions:
  echoMessage:
    properties:
      message:
        type: "string"
  searchMessage:
    properties:
      message:
        type: "string"

1 Answers1

-1

You are getting a 403 error, which means your preflight request lacks the proper authentication to pass the access control check.

In this case, the CORS configuration of the resource the requests are headed to should include an Access-Control-Allow-Origin header. This header should contain all the HTTP origins that are allowed to access the resource.

Just in case, you should add one or more Access-Control-Request-Header headers, whose values must match the ResponseHeader values in the CORS configuration. All the headers in the Access-Control-Request-Header should be present in the Access-Control-Allow-Origin header in the CORS configuration so the request can be authorized.

You can find more information about proper authentication here.

Rodrigo C.
  • 1,114
  • 7
  • 13