GET request with Basic Auth working from Postman but not from the browser
Asked Answered
L

4

9

I'm working with an odata api, and when I'm using postman to do a GET request, works perfect and I get the response as I was expecting. Postman Request

But when I use a fetch request from my React app, the request throws a 401, using the same headers as I previously used in Postman. and it says that 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:3000' is therefore not allowed access. The response had HTTP status code 401.

Any idea about how to solve this request? Thanks!

fetch('https://api4.successfactors.com/odata/v2/', {
  method: 'GET',
  headers: {
    authorization: `Basic ${auth}`, //auth is the encoded base64 username:password
  },
})
  .then(response => response.json())
  .then((response) => {
    console.log('in response: ', response);
  })
  .catch((error) => {
    console.log('in fetchJobs error: ', error);
  });

This is the 401 that I'm getting.... enter image description here

Lobule answered 1/3, 2018 at 14:3 Comment(0)
M
24

This is most likely because Postman is probably not sending a preflight Options request before your GET, and upon receipt of the GET response doesn't perform any kind of cors check (since it wouldn't really make sense to anyway).

On the other hand, when running code from your webpage Chrome is both performing a preflight Options in order to ascertain what cross-domain request parameters it's allowed to send to the remote server and checking if the response to the Options req has the appropriate Access-Control-Allow-Origin header on to authorise your origin (i.e. the domain of the page you're making the request from).

Typically, a preflight Options is sent to the server by a browser to ask the server if it's allowed to perform the operation it's about to perform - in your case, a GET. If the remote (cross-domain) server doesn't respond to the prelight Options request with the correct headers in the response authorising your GET then the browser won't send one. You're not even getting that far however, since the response to your Options request doesn't even itself pass a cors origin check.

If you control the server, you need to respond to the Options request by setting the Access-Control-Allow-Origin header on the response to include the origin of your request page, and also to set the Access-Control-Allow-Methods to include GET (and probably OPTIONS). If you don't control the remote server, it's likely any normal api service such as the one you're trying to hit has some configuration in their backend you can set somewhere to authorise your origin.

You can read up more on cors behaviour here

Moralist answered 1/3, 2018 at 14:40 Comment(7)
Hi @Rhys, and if I don't have access to the backend... (that's the case) How can I solve the issue?Lobule
@JCGarcia I just updated my answer to include a little bit of info on that - but basically, if you're hitting some standard service that you have an account against or similar, I'd expect them to expose some options in their backend config that you can set to whitelist your domain/originMoralist
@JCGarcia for info, you wouldn't have this issue if you were making the request from the same domain as the server you're trying to hit. If you made the request server-side you also wouldn't have this problem, although it's worth considering carefully the security/safety implications of any decision you make, as that's part of what CORS is there to help with in the first placeMoralist
I understand the considerations on security, In fact that api doesn't allow anything but read data. That's why a request from client side it would be ideal. Also because the whole app is serverless and I would love to keep it that way. Now That you explained the CORS problem, (thanks btw, is a really good one) next thing would be find a third party service, any recommendation?Lobule
@JCGarcia when I mentioned thirdparty service in the answer I meant the service (behind the server) you're hitting - presumably, whoever wrote the service you're trying to talk to would have also considered cross-domain req implications and should have a solution (or not want one, for some reason). That's why I'd expect them to expose some way to tell them about your site (or not, if they don't want to do that for some reason)Moralist
ok.... so as far as I understand, there's no solution client side. I should set up a server to solve it... right?Lobule
Let us continue this discussion in chat.Lobule
A
3

You are experiencing a CORS issue, in order to get past it you need to enable CORS on your backend.

Aisne answered 1/3, 2018 at 14:33 Comment(3)
Hi @Mike_Tung, unlucky for me... I don't have access to the backend, so that would be impossible... 😥. Any idea to bypass that?Lobule
It’s not possible to bypass because it’s purely backend security preventing you from accessing resource, you could deploy on exact same server but it’s riskyAisne
What it would be the easiest solution? set up a server? only for 1 query seems excessive... but if so, what would you recommend?Lobule
O
0

Ideal way is to allow at your server to allow calls from different domain, but if you don't have access to back-end, and testing services, you can install this chrome plugin to bypass pre-flight requests. cors chrome extension

Orvieto answered 21/2, 2019 at 11:29 Comment(0)
S
0

Configuring cors to accept my domains, as well as using {withCredentials: true} in my axios request removed the error:

Before: axios.get(URL).then(response => {})

After: axios.get(URL, {withCredentials: true}).then(response => {})

Screwworm answered 12/3, 2024 at 13:34 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.