CORS policy issue - node.js

I am in a team doing a client-server application. We are using Node.js (v12.18) in the backend as an API, and React (v16.13) for the frontend. Recently I've found this bug related to the CORS policy. I'm trying to send a POST request, deleting one resource in the database and when trying to delete it, this is the error I get:
Access to fetch at 'http://localhost:8080/clientes/eliminar' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
As far as I researched in forums and discussions I always find the same resolution, which is using the "Access-Control-Allow" headers, but we are already using them. I tried to change the POST method by a DELETE method when doing the request, but I find the same issue.
The headers that we are currently using in the backend, in case someone wonders what we have.
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Credentials", "true");
res.header("Access-Control-Allow-Methods", "GET, POST");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");
next();
});
The sites I visited in order to solve the problem were pretty much the same as this one
TYSM for reading until here and ask for more information you need. Every piece of help is appreciated.

Have you already tried to add CORS to the project and use it as a middleware?
//...
const cors = require('cors')
//...
app.use(cors())

Related

CORS on Azure Web App returning error: No 'Access-Control-Allow-Origin

I have an Azure static web app running my frontend and an Azure web app running my backend. I've been using this app for a couple of months. Today, after deploying some changes, my backend has been responding with CORS errors. Specifically, the error is:
Access to XMLHttpRequest at 'https://memoriesforusbe.azurewebsites.net/auth?userEmail=xxxxxxxxxxxxxxx&userPassword=xxxxxxxxxxxxx' from origin 'https://www.memoriesforus.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
UPDATE: I did some more testing this morning and have found that the response is different depending on the user. This makes NO sense to me that a CORS response is based on the data being sent in? More confused than before.
The headers that I had in my node.js server file were:
res.header("Access-Control-Allow-Origin", "https://login.memoriesforus.com");
res.header("Access-Control-Allow-Origin", "https://www.memoriesforus.com");
To try to fix it, I added the following in hopes the wildcard might help.
res.header("Access-Control-Allow-Origin", "https://*.memoriesforus.com");
res.header("Access-Control-Allow-Origin", "https://memoriesforus.com");
I also noticed that Azure Web Apps has a blade for CORS. I tried adding my headers there and had the same result.
The error occurred on the login screen of the app. I have a couple of apis that don't require the user to be logged in or use tokens. So I tried those and they seem to be working. So I'm thinking it may have something to do with that?
I'm just very confused because the original request headers worked for so long. Is there something else I should be looking at that might cause this error? The changes I made in the backend were unrelated to CORS. Not sure if something changed on the app service? I also uploaded changes to the frontend. But the call to the api that is getting the error was also unchanged.
The whole CORS related section of the node.js server file currently looks like this:
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://login.memoriesforus.com");
res.header("Access-Control-Allow-Origin", "https://www.memoriesforus.com");
res.header("Access-Control-Allow-Origin", "https://*.memoriesforus.com");
res.header("Access-Control-Allow-Origin", "https://memoriesforus.com");
res.header("Access-Control-Allow-Origin", "https://salmon-plant-09df42110.2.azurestaticapps.net"); //the auto generated name of the frontend on Azure
if(process.env.SERVER_STATUS === 'Dev' ) {
res.header("Access-Control-Allow-Origin", "*"); }
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
if (req.method === "OPTIONS") {
res.header("Access-Control-Allow-Methods", "PUT, POST, PATCH, DELETE, GET");
return res.status(200).json({});
}
next();
});
You may have zero or one Access-Control-Allow-Origin headers. You can't have two or more.
The * character is a special value meaning "any origin", it isn't a placeholder that can be included in the allowed origin as a wildcard for part of the origin.
To allow multiple, but not all, origins you need to:
Read the Origin request header
Compare it to whatever rules you care to write to see if it is an allowed origin
Include res.header("Access-Control-Allow-Origin", the_origin_request_header_value); if it is one
You appear to be using Express, if so the cors module will handle this for you (and allow you to specify valid origins as a list, a regular expression, or a custom function).
I found this article which ended with the problem being the data. So I created a new user and tried with that user. The api works fine. So I will close this question and work on why my data is giving a CORS error. Never occurred to me that it could be the data itself.

post request to Express.js api from another computer

I have a server running on localhost:3000, and I set my app.js to use the angular router when I try to access localhost:3000 in my browser
(example :app.use('/', express.static(path.join(__dirname, '/dist/Client')));)
When I make a post request to my api I do:
const headers = new Headers({
'Content-Type': 'application/json'
});
const options = new RequestOptions({
headers: headers
});
this.http.post('http://localhost:3000/api/someAction',{body},options)
.toPromise()
.then(//function)
Untill now everything is correct, but how can I make my server accessible from another computer. For example if another computer on the same network knows the private IP address of the server I want him to be able to access my app when he navigate to for example 192.168.1.10:3000. Right now I can access but all my http requests fail and I have the following error
Access to XMLHttpRequest at 'http://localhost:3000/api/someFunction'
from origin 'http://192.168.1.10:3000' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: It does not
have HTTP ok status.
In app.js I have the following:
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");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
next();
});
This is a CORS error message you're getting.
You can use the Express CORS middleware to allow calls from other origins to your server. Make sure to choose the right options to allow calls from your other PC.
https://expressjs.com/en/resources/middleware/cors.html
And also make sure to place the CORS middleware at the top of your application definition.
const app = express();
app.use(cors({ origin: "*" })); // Do this first
//... the rest of your routes and handlers and middlewares
From your local machine where things seem to work correctly, open your Chrome Dev Tools, and make sure OPTION calls are being made and fulfilled successfully, and that proper headers are being returned.
Lastly, from a security perspective, remove or restrict the CORS options as much as possible for your production environment. Only use flexible CORS policy during development and testing.

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://localhost:3000/ [duplicate]

This question already has an answer here:
CORS Error: “requests are only supported for protocol schemes: http…” etc
(1 answer)
Closed 3 years ago.
SOLUTION: It turns out I needed to change https://localhost:3000, to http://localhost:3000. (My follow-up question would be why this is the case, especially as my code worked for https://www.remoteserver.com/`).
I have a development server at https://localhost:3000 and a production server at https://www.remoteserver.com (Node.js/Express). My client is at https://localhost:4200 (Angular).
I fixed the Cross-Origin Request Blocked issue with https://www.remoteserver.com, using the code as below:
var cors = require(cors());
app.use(cors());
app.options('*',cors());
var allowCrossDomain = function(req,res,next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
app.use(allowCrossDomain);
But using the same code for my development server https://localhost:3000 I am still facing the CORS blocked issue, and I haven't been able to get rid of the problem.
Is there any reason that the code above would work for the production server but not for the development server?
Any ideas on a fix or what I should try next?
Many thanks!
The three solutions, avoiding CORS problem
Allow CORS to server side
Use proxy server
Use JSONP
Try to use as the following way
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, PUT, POST");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
Get know details link

Allowing Multiple Cors In Node Express

I'm trying to allow multiple cors with node in my express api, I've been able to get it to work but am currently facing two issues.
I can't connect to my api using postman because I checked and it turns out the origin sent from postman is undefined.
I have a mobile app which also communicate with the server, the issue is after I allowed multiple specific origin, the app also can't communicate with the server.
How do I solve this issue, because I can't leave my api server open to allow communication from every origin.
Have you tried with Cors for nodejs
Add the dependency:
$ npm install cors --save
And then add cors to your app.js
var cors = require('cors')
var app = express()
app.use(cors())
On production try this instead of * on Access-Control-Allow-Origin header, For development allow any source will not be a problem (depend on your scenario)
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "yourdomain.com");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.use(function(req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.setHeader('Access-Control-Expose-Headers','Content-Type,expire');
next();
});
Try this one in your server. If you want to pass extra header parameter you need to add those variable in res.setHeader('Access-Control-Allow-Headers', 'Content-Type , token'); but remember don't user '-' in the variable name.

AngularJS cross domain request to separate ExpressJS App hosted on Heroku

I have a stand-alone ExpressJS API that I have built that should be able to service mobile apps and web apps. I'm trying to test the API using a simple AngularJS client app that I have built. The API service runs fine when I host it locally.
I'm getting Cross Domain Request errors when trying to make a GET call to the API hosted on my external server. I'm using Chrome v39
EDIT: my error turns out to be an incorrect URL reference to my heroku API. Please see my answer, below.
XMLHttpRequest cannot load http://myservice.heroku.com/some-api-endpoint?request-parameter=value. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin http://localhost:5001 is therefore not allowed access.
After reading and scanning numerous articles, I've tried the following:
CORS Code on the API
Added to app.js
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
res.header("Access-Control-Allow-Headers", "Cache-Control, Pragma, Origin, X-Requested-With, Content-Type, Accept");
res.header("Access-Control-Max-Age", "1728000");
res.header("Access-Control-Expose-Headers", "Cache-Control, Pragma, Origin, X-Requested-With, Content-Type, Accept");
if (req.method === 'OPTIONS') {
res.statusCode = 204;
return res.end();
} else {
return next();
}
});
CORS Code on the API (Attempt 2)
Using the CORS node_module instead of the above, yields the same errors
Added to Package.json
"cors" : "~2.5.2"
Added to app.js
var cors = require('cors');
app.use(cors());
Client Code (Attempt 1)
$http({
url: 'http://myservice.heroku.com/some-api-endpoint?request-parameter=value',
method: 'GET',
headers : {
"Origin" : "myclient.heroku.com",
"Access-Control-Expose-Headers": "X-Requested-With",
"Access-Control-Request-Method" : "GET",
"Access-Control-Request-Headers" : "Origin, X-Requested-With, Content-Type, Accept"
}
})
Errors in the chrome dev console:
Refused to set unsafe header "Origin" angular.js:9625
Refused to set unsafe header "Access-Control-Request-Method" angular.js:9625
Refused to set unsafe header "Access-Control-Request-Headers" angular.js:9625
XMLHttpRequest cannot load http://myservice.heroku.com/some-api-endpoint?request-parameter=value, which is disallowed for cross-origin requests that require preflight. (index):1
Client Code (Attempt 2)
thePath = 'http://myservice.heroku.com/some-api-endpoint?request-parameter=value'
+'&callback=JSON_CALLBACK';
$http.jsonp(thePath)
.success(function(data){
console.log(data);
});
Errors received in the Chrome Dev Console:
Uncaught SyntaxError: Unexpected token : endpoint?request-parameter=value&callback=angular.callbacks_0:1
This has been stumping me for two days. Any help is appreciated!
The error turned out to be the reference to applications hosted on Heroku. I was attempting to make my get requests to myapp.heroku.com and not myapp.herokuapp.com. This is a subtle difference that caused there error.
Using cURL or typing in the request into the browser's address bar for myapp.heroku.com will redirect your request to myapp.herokuapp.com and complete the request successfully. However, made from Angular.js $http() function resulted in the Cross Domain error.
The simplest problems seem to cause the most confusion.
You are taking a convoluted route for CORS. Use nodejs CORS middleware to do your stuff....
add,
"cors": "^2.5.1",
to your dependencies in package.json & in app module,
var cors = require('cors');
//add cors to do the cross site requests
app.use(cors());

Resources