24

I created login FE and finished it. And as per usual my goto for ajax was Axios. My code is as follows.

const baseUrl = http://localhost:5000/project/us-central1/api

Axios.post(
 `${baseUrl}/v1/user/login`,
 { ...data },
 {
  headers: {
   Authorization: 'Basic auth...'
  }
 },
).then(r => console.log(r).catch(e =>console.log(e));

Now when i try to send request to my local firebase cloud function. I get a 400 bad request.

response

after checking the request, I was wondering why it wasn't sending any preflight request, which it should do(to the best of my knowledge) but instead I saw a header named Sec-Fetch-Mode. I searched anywhere it's a bit abstract. And I can't seem to figure anything why my request still fails.

Is there anything Im missing in my config of axios?

My FE is running on a VSCode Plugin named live server(http://127.0.0.1:5500)

Also, my firebase cloud function has enabled cors

// cloud function expres app
cors({
 origin: true
})

Any insights would be very helpful.

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
Reyn
  • 757
  • 1
  • 5
  • 16

2 Answers2

57

The OPTIONS request is actually being sent, because you are sending a cross-origin request with an Authorization header which is considered as non-simple. It doesn't show in developer tools because of a feature/bug in Chrome 76 & 77. See Chrome not showing OPTIONS requests in Network tab for more information.

The preflight request is a mechanism that allows to deny cross-origin requests on browser side if the server is not CORS aware (e.g: old and not maintained), or if it explicitly wants to deny cross-origin requests (in both cases, the server won't set the Access-Control-Allow-Origin header). What CORS does could be done on server side by checking the Origin header, but CORS actually protects the user at browser level. It blocks the disallowed cross-origin requests even before they are sent, thus reducing the network traffic, the server load, and preventing the old servers from receiving any cross-origin request by default.

On the other hand, Sec-Fetch-Mode is one of the Fetch metadata headers (Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site and Sec-Fetch-User). These headers are meant to inform the server about the context in which the request has been sent. Based on this extra information, the server is then able to determine if the request looks legitimate, or simply deny it. They exist to help HTTP servers mitigate certain types of attacks, and are not related to CORS.

For example the good old <img src="https://mybank.com/giveMoney?amount=9999999&to=evil@attacker.com"> attack could be detected on server side because the Sec-Fetch-Dest would be set to "image" (this is just a simple example, implying that the server exposes endpoints with the GET method with unsafe cookies for money operations which is obviously not the case in real life).

As a conclusion, fetch metadata headers are not designed to replace preflight requests, but rather to coexist with them since they fulfill different needs. And the 400 error has likely nothing to do with these, but rather with the request that does not comply with the endpoint specification.

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • @Mr. Flibble Can you please edit the original post so it focuses on the bounty? Or maybe take the bounty away? It was just a typo in the Javascript! – santamanno Aug 27 '19 at 22:28
  • @santamanno, it was a typo. it it was really a spread, as for the answer. I really don't know why it happened(400 error). But, when I added, `responseType: json, and Cache-Control: no-cache, Content-Type: aplication/json` and it works. – Reyn Aug 30 '19 at 10:19
  • Using `POST` is not sufficient to make a CORS request 'simple'. The custom header `Authorization` and the `Content-Type: application/json` shown in the question will both trigger a preflight OPTIONS request. The reason the preflight request was not shown in the developer tools is because of a feature/bug in Chrome 76 & 77. See https://stackoverflow.com/questions/57410051 for more information. – skirtle Jan 06 '20 at 09:20
  • @skirtle thanks for pointing out that there are some non-simple headers that should trigger the preflight request. I'm editing my answer – Guerric P Jan 06 '20 at 09:35
  • Any idea what this header means: `Sec-Fetch-User: ?1` ? See related question here: https://stackoverflow.com/questions/59860648/incoming-sec-fetch-user-1-header-messes-up-my-request-throttling – user2173353 Jan 22 '20 at 13:19
-1

You are missing a dot on your spread operator, this is the correct syntax:

{ ...data }

Note the three dots before “data”.

Please see the use of spread operators with objects here:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

santamanno
  • 626
  • 4
  • 12