5

I am making a request to an API that I have on my computer (192.168.1.132) with react native from my phone (in the same network):

fetch('http://192.168.1.132:8000/test', {
  method: 'GET',
  headers: { 'Authorization': 'Bearer 4uFPmkP5326DXcRuHDKjRRrmhdeIBJ'},
  credentials: 'same-origin'
  })
  .then((response) => response.json())
  .then((responseJson) => {
    console.log('RESPONSE: ' + JSON.stringify(responseJson))
  })

But I am sniffing the request and it has not the Authorization header (any other that I put will appear, but not Authorization). In Xcode I have enabled 'AllowArbitraryLoads'. So my API returns 401 (Unauthorized) because obviously there is no Authorization header. Why is it not included in my request?

epord
  • 451
  • 6
  • 16
  • Try this [using an authorization header with fetch in react native](https://stackoverflow.com/questions/30203044/using-an-authorization-header-with-fetch-in-react-native) – tarzen chugh Mar 17 '18 at 18:48
  • That looks right, it should work. I personally never used that `credentials` property though. – Noitidart Mar 17 '18 at 18:59
  • Try using `credentials: 'include'` instead. Unless your frontend JavaScript is also running from the origin `http://192.168.1.132:8000`, your code’s making a cross-origin request. But with `credentials: 'same-origin' ` you’ve told the browser to only include credentials in same-origin requests, no cross-origin ones. The Authorization header (for HTTP authentication) is a type of credential https://fetch.spec.whatwg.org/#credentials, so the browser omits it unless (by using `credentials: 'include'`), you explicitly indicate you always want credentials included — even for cross-origin requests – sideshowbarker Mar 17 '18 at 22:12
  • By the way, you’ll need to make sure the `http://192.168.1.132:8000/test` endpoint allows unauthenticated OPTIONS requests — that is, without the Authorization header. Because including the Authorization header triggers your browser to automatically on its own first send a CORS preflight OPTIONS request https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Preflighted_requests but the browser always omits all credentials from that OPTIONS request. So if that `http://192.168.1.132:8000/test` endpoint requires the Authorization header in OPTIONS requests too, the preflight will fail. – sideshowbarker Mar 17 '18 at 22:21
  • And to be clear, just because your frontend JavaScript code is also running on a `192.168.1.132` server doesn’t make the request same-origin. It would only be same-origin if the port number of the server for your frontend code is the same as the port number of the server you’re sending the request to. So unless your frontend code is also running from the server on port 8000, then the request your code is making is a cross-origin request. – sideshowbarker Mar 17 '18 at 22:24

2 Answers2

10

You need a trailing slash on your url for headers to attach. As pointed out in the comments, make credentials say 'include'. If your API attaches a CSRF token in the pre-flight, then it will include that cookie as well.

Ryan Dines
  • 979
  • 10
  • 18
1

First I was just using the following in my Node Express API:

app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authentication");
  next();
});

It didn't work fine from react app but it worked from Insomnia directly request, then I needed to add the following:

const cors = require('cors');
app.options('*', cors())
Jeff Pal
  • 1,519
  • 1
  • 17
  • 28