Fetch in ReactJS with Basic Auth return 401 (Unauthorized). Preflight request doesn't pass access control check
Solution 1
You're trying to access port 4000 (your API, or backend) from port 3000 (Your client). This violates the Same-origin policy, even though you're clearly running both the client and the API from the same machine.
To get around this the easiest way is to just fire up your client from the same port as your API (port 4000) this should allow your host to see that you're trying to access resources from the same domain/port which won't force a preflight request.
If that's not possible you'll have to configure CORS for your API, and this question doesn't give any details about the backend so I can't instruct you on how to do that at the moment.
And of course this approach obviously won't work if you're running two separate servers in production, but that's probably outside of the scope of this question.
Solution 2
It may not be the same problem as the OP, but I was able to get basic auth protected fetch
es working just by adding a credentials mode...
fetch(
'http://example.com/api/endpoint',
{ credentials: "same-origin" }
)
See here: https://github.github.io/fetch/ under Request > Options
rk_Tinelli
Updated on July 10, 2022Comments
-
rk_Tinelli almost 2 years
I'm new at ReactJS but I'm trying to learn by myself now. I'm facing a problem when I try to add data do may Database, in my RestAPI with MongoDB, using fetch function on my web Application. When I click my button, it runs the following code:
SubmitClick(){ //console.log('load Get User page'); //debug only fetch('http://localhost:4000/users/', { method: 'POST', headers: { 'Authorization': 'Basic YWRtaW46c3VwZXJzZWNyZXQ=', 'Content-Type': 'application/json', }, body: JSON.stringify({ email: '[email protected]', first_name: 'Wade', last_name: 'Wilson', personal_phone: '(11) 91111-2222', password: 'wolv3Rine' }) }) //this.props.history.push('/get'); //change page layout and URL }
and I get the following message on my browser:
OPTIONS http://localhost:4000/users/ 401 (Unauthorized)
Failed to load http://localhost:4000/users/: 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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Uncaught (in promise) TypeError: Failed to fetch
My RestAPI have Basic Auth, but i don't know what i'm supposed to insert in headers to have access. I got this
'Authorization': 'Basic YWRtaW46c3VwZXJzZWNyZXQ=',
from Postman, when I configured the Authorization tab, and it was automatically added to the headers.I'm using Google Chrome as my default browser.
My backend code is the following:
const express = require('express'); const bodyParser = require('body-parser'); const mongoose = require('mongoose'); var basicAuth = require('express-basic-auth') const app = express(); mongoose.connect('mongodb://localhost/usersregs', { useMongoClient: true }); mongoose.Promise = global.Promise; app.use(basicAuth({ users: { 'admin': 'supersecret', 'adam': 'password1234', 'eve': 'asdfghjkl' } })) app.use(bodyParser.json()); app.use(function(err, req, res, next){ console.log(err); //res.status(450).send({err: err.message}) }); app.use(require('./routes/api')); app.listen(4000, function(){ console.log('Now listening for request at port 4000'); });
-
Scott over 6 years
-
HMR over 6 yearsWhat is the url of the page in the browser? If it's not
http://localhost/4000
(maybe because you're using webpack) then your API server should set aAccess-Control-Allow-Origin
header -
rk_Tinelli over 6 yearsThe url int he browser is
http://localhost:3000/
. I'm trying to figures it out how to set thisAccess-Control-Allow-Origin
, I'll add my backend code here. @HMR -
HMR over 6 yearsthe easiest way would be to install the
Allow-Control-Allow-Origin: *
extension for chrome: chrome.google.com/webstore/detail/allow-control-allow-origi/… -
rk_Tinelli over 6 yearsI'm trying to avoid that since this project will need to run in another computer that I'm not responsible for. I'll give instructions to the end user, but maybe there is a way to do this programmatically.
-
HMR over 6 yearsIf you're running your front end code with webpack dev server then just connect to same host as your web page (your api calls should not have the host and port in the url anyway but just the absolute path
/API/SOMEAPI
) dev server allows you to proxy these requests to somewhere: webpack.js.org/configuration/dev-server/#devserver-proxy
-
-
rk_Tinelli over 6 yearsI couldn't get then to run in the same port in this scenario, if my backend is already running in port 3000, for example, when i give to command
npm start
to my client i get the following message:? Something is already running on port 3000. Would you like to run the app on another port instead? (Y/n)
But, in the opposite scenario, I mean, if my client is already running at port 3000 and send to commandnode index
do my backend, it works fine. I'll edit my question with my backend code, because each system running in different ports. Thanks for the reply by the way. -
rk_Tinelli over 6 yearsHere, I edited my question with my index.js code for my backend.
-
rk_Tinelli over 6 yearshey @JoshSiegl I think it is working now, I followed the instructions in this link link. Now I'm getting a 401 error, which is related to unauthorized access. I'm already searching for it
-
Josh Siegl over 6 yearsAwesome @rk_Tinelli, that's good news. I'm glad I could help.
-
Michael Qin over 4 yearsHi @rk_Tinelli, how did you solve the 401 issue with basic auth? Would you like to share? Thanks, I guess setting
credentials: "include"
in the request headers might be the solution? -
rk_Tinelli over 4 yearsHey @MichaelQin unfortunately i had to drop this project after a few weeks due to some changes in my work, so i don't have a proper solution for that, but thanks for bringing a new suggestion.