CORS fetch from Firefox to Beego server stops after pre-flight
Asked Answered
G

1

6

I have an ecmascript 7 browser application running on http://localhost:3000 in a Firefox 44.0.2 browser. It is posting to a Beego 1.6.0 server running on https://localdev.net:8443. The 'localdev.net' is on the same box and resolves to the localhost address. The browser code is:

var serverURL = 'https://localdev.net:8443/v1/user/login'
fetch(serverURL, {
  method: 'post',
  headers: {
    'Accept': 'application/json',
    'Content-Type': 'application/json'
  },
  mode: 'cors',
  cache: 'default',
  body: JSON.stringify({username: this.state.username, password: this.state.password})
})
.then(function(response){
  if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
  }
  return Promise.reject(new Error(response.statusText))
})
.then(function(data){
  console.log('data: ' + data)
})
.catch((err) => console.error(serverURL, err.toString()))

}

The beego server is configured to handle CORS requests as follows:

beego.InsertFilter("*", beego.BeforeRouter, cors.Allow(&cors.Options{
  AllowOrigins:     []string{"*"},
  AllowMethods:     []string{"*"},
  AllowHeaders:     []string{"Origin"},
  ExposeHeaders:    []string{"Content-Length"},
  AllowCredentials: true,
}))

Wireshark sees the client sending a pre-flight CORS options request to the server:

OPTIONS /v1/user/login HTTP/1.1\r\n
Host: localdev.imaginout.net:8443\r\n
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:44.0) Gecko/20100101 Firefox/44.0\r\n
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n
Accept-Language: en-US,en;q=0.5\r\n
Accept-Encoding: gzip, deflate, br\r\n
Access-Control-Request-Method: POST\r\n
Access-Control-Request-Headers: content-type\r\n
Origin: http://localhost:3000\r\n
Connection: keep-alive\r\n

In response, the beego server outputs:

2016/03/05 12:54:29 [router.go:828][D] | OPTIONS    | /v1/user/login                           | 102.08µs         | not match   |

Even though the server says 'not match', wireshark records a response:

HTTP/1.1 200 OK\r\n
Access-Control-Allow-Credentials: true\r\n
Access-Control-Allow-Origin: http://localhost:3000\r\n
Access-Control-Expose-Headers: Content-Length\r\n
Server: beegoServer:1.6.0\r\n
Date: Sat, 05 Mar 2016 17:54:29 GMT\r\n
Content-Length: 0\r\n
Content-Type: text/plain; charset=utf-8\r\n

To me, the 200 status with an Access-Control-Allow-Origin set to the browser app's domain indicates that the CORS pre-flight succeeded, but the Firefox developer console shows:

"https://localdev.net:8443/v1/user/login" TypeError: NetworkError when attempting to fetch resource.

So the app and/or Firefox seems to think the request failed. Wireshark shows that the app does not send another request to the server. I'm expecting a post.

There are a LOT of questions about CORS out there, but the browsers/APIs/servers are highly variable so I haven't found an exact match. Digging into it, but any help would be appreciated.

Gimmick answered 5/3, 2016 at 18:20 Comment(2)
Tried running the request from Chrome and it gives an additional error in the developer console: "Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response." After this error it prints "TypeError: Failed to fetch".Gimmick
Set AllowHeaders to "Origin, Content-Type" in the Beego configuration, but still get the same error. The pre-flight response sent by Beego does not contain an Access-Control-Allow-Headers set to 'Origin, Content-Type'. I suspect it should.Gimmick
G
3

Fixed. Need to set Access-Control-Allow-Headers to []string{"Origin", "Content-Type"} in the Beego CORS options. Then the Access-Control-Allow-Headers is set properly and the pre-flight succeeds. After this the main post succeeds.

Gimmick answered 5/3, 2016 at 20:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.