Socket.io , NodeJS and ReactJS CORS error - javascript

As a starter, I have read a bunch of question concerning the same issue.
When I open the connection with the socket via React client the normal way, just the URL as parameter, I don't get this error, connection established.
But when I do this:
const io = ioClient(webSocketUrl, {
transportOptions: {
polling: {
extraHeaders: getAuthenticationToken()
}
}
});
The request return a CORS error everytime.
I have tried to:
Set the origin like so: io.origins(['*:*']);
app.use(function (req, res, next) {
res.setHeader(
"Access-Control-Allow-Origin",
req.header("origin") ||
req.header("x-forwarded-host") ||
req.header("referer") ||
req.header("host")
);
res.header(
"Access-Control-Allow-Methods",
"GET, POST, OPTIONS, PUT, PATCH, DELETE"
);
res.header("Access-Control-Allow-Headers", "X-Requested-With,content-type");
res.setHeader("Access-Control-Allow-Credentials", false);
next();
});
And also this:
app.use(cors());
app.options("*", cors());
None of the above worked.
I would appreciate any help.

Found the answer!
For anyone with the same problem, this is how I've done it:
const io = require("socket.io")(server, {
handlePreflightRequest: (req, res) => {
const headers = {
"Access-Control-Allow-Headers": "Content-Type, Authorization",
"Access-Control-Allow-Origin": req.headers.origin, //or the specific origin you want to give access to,
"Access-Control-Allow-Credentials": true
};
res.writeHead(200, headers);
res.end();
}
});

Related

NodeJS and ReactJS: Cookies do not set in browser

I am trying to send cookies in axios request from request handled in node js, NodeJS Does send cookies in response header but does not set in browser.
ReactJS
axios.post('http://localhost:4000/api/v1/auth/mflogin', {
data: wrapper,
},
)
.then((response) => {
setUser(true);
console.log(response.data);
navigate('/home');
})
.catch((error) => {
console.log('Error adding note.', error);
navigate('/countertwo');
});
This my backend:
One
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'http://localhost:8080');
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('Allow', 'GET, POST, PUT, DELETE, OPTIONS, HEAD');
res.header('X-Powered-By', '');
next();
});
app.options('*', cors()) // include before other routes
const candidateAuth = require('./routes/Candidate/auth');
app.use('/api/v1/auth/', candidateAuth);
Two
if (validPassword) {
assign(User.dataValues, { Verified: true });
response.cookie('BasicCookie', 'BasicCookie',{httpOnly: true, sameSite: 'strict', secure: 'true',maxAge:1000000000000 }).status(201).json({
User,
});
} else {
response.status(400).json({ error: "Invalid Password" });
}
But it does send cookie to post man request,
But it does come in response header but do not set in cookies?
Any to help me here??

Express + Passport + CORS: session allowed for multiple domains

I am trying to make the frontend (React JS) work with my backend server (Express JS). I am still fighting with CORS. The frontend requests are still blocked by CORS.
According to CORS documentation I have set my Express instance to use cors() as middleware:
const app = express();
// Middlewares
const whitelist = [
'http://localhost:3000',
'http://localhost:3001'
];
const corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
};
app.use(cors(corsOptions));
If someone asks why am I using CORS with localhost at all, is because I was told to do so since I had to send withCredentials: true header from axios requests to persist session after login.
I just added axios.defaults.withCredentials = true to intercept requests in the frontend.
The way it was working before adding more domains to corsOptions was setting up a middlewares to let the server work with the frontend:
export const setHeaders = (req, res, next) => {
res.header('Access-Control-Allow-Origin', process.env.APP_URL);
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
};
...
app.use(setHeaders);
If I remove the previous code, it won't work even for one domain.
So, what I have to change in order to let the server fetch data from multiple domains? Thanks in advance.
Add credentials and allowedHeaders options to your corsOptions config
credentials: true,
allowedHeaders: ['Origin, X-Requested-With, Content-Type, Accept'],
Read https://www.npmjs.com/package/cors#configuration-options
Also, you can whitelist domains with 127.0.0.1 as you might want to access them via localhost or 127.0.0.1
Full code
const app = express();
// Middlewares
const whitelist = [
'http://localhost:3000',
'http://127.0.0.1:3000'.
'http://localhost:3001',
'http://127.0.0.1:3001',
];
const corsOptions = {
credentials: true,
allowedHeaders: ['Origin, X-Requested-With, Content-Type, Accept'],
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
};
app.use(cors(corsOptions));

Why isn't my Fetch request sending custom headers in React-Native?

I am calling a fetch request akin to this.
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: new Headers({
'custom-header': 'custom header value'
})
}
)
.then(res=>{
/* code */
})
.catch(err=>{
/* code */
})
But it seems that the header is not being sent to the server. The server runs on Node.js, and I am attempting to reach it with React-Native.
I have allowed "access-control-allow-origin": "*" on the server, but to no avail.
I can also reach other endpoints on the server that don't require any headers.
And lastly, I have set the headers with both new Headers() and as an object.
What exactly am I missing to allow the headers to be sent? Is there a way to see exactly what is going on with my request in react-native?
It works in postman just fine.
EDIT:
I am using the cors middleware in my server.
app.use(cors())
appConfig.init(app);
Can you add these lines before using routes and try?
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",
"Origin, X-Requested-With, Content-Type, Accept, Authorization, custom-header"
);
res.header("Access-Control-Expose-Headers", "custom-header");
next();
});
And if you are using express cors middleware, you can add allowedHeaders and exposedHeaders options.
https://github.com/expressjs/cors#configuration-options
note if these configuration replaces the default headers, you may need to add the default headers to the options.
app.use(
cors({
exposedHeaders: ["custom-header"],
allowedHeaders: ["custom-header"]
})
);
Lastly you had better to use fetch api like this to send headers:
fetch('https://api-endpoint.com/api',
{
method: "POST",
headers: {
"custom-header": "custom header value"
}
}
)
.then(res => {
/* code */
})
.catch(err => {
/* code */
})
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Be sure,you added the header in:
res.header(
"Access-Control-Allow-Headers",
"Your_OWN_header,...."
);

CORS Error: Angular.JS, Node.JS and Express [duplicate]

This question already has answers here:
Why doesn't adding CORS headers to an OPTIONS route allow browsers to access my API?
(36 answers)
Closed 7 years ago.
Having issues getting data back from a http post request to an API I've been building. Throws the error:
XMLHttpRequest cannot load (URL to API here). No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:9000' is therefore not allowed
access.
Here's the Angular code on the client side:
$http.post('MyAPIsURLHere', {
date: $scope.information.PubDate
})
.then(console.log)
.catch(console.error);
And here's the Node server side code for my API:
app.post('/getThing', (req, res) => {
const date = req.body.date;
const query = Overquery
const query2 = "alter session set nls_date_format = 'MM/dd/yyyy'";
oracleDB.execute(query2, (err, result) => {
if(err) {
console.error(err);
}
else {
console.log(result);
}
});
oracleDB.execute(query, (err, result) => {
if(err) {
console.error(err);
}
else {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'POST');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.json(result.rows);
}
});
});
First time building an API so any suggestions and help would be greatly appreciated!
Run the following in your project from a bash shell:
npm install cors --save
It will install this:
https://github.com/expressjs/cors
Then add this to your server when creating the app.
var express = require('express');
var cors = require('cors');
var app = express();
app.use(cors());
Edit: This will enable CORS for every domain wich is not recomended for security reasons. Check here for further CORS configuration: https://github.com/expressjs/cors#configuring-cors
In your node application, this sample of code should solve your issues:
// Allowing X-domain request
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", "Origin, X-Requested-With, Content-Type, Accept, Cache-Control");
// intercept OPTIONS method
if ('OPTIONS' == req.method) {
res.send(200);
}
else {
next();
}
};
app.use(allowCrossDomain);

Making CORS Request in Node.js/Express and AngularJS

I have seen many answers in stack overflow which says setting response headers will make you "CORS" request.But no solution worked for me.I have written the following code:
//Server.js Code
var express = require('express'),
app = express();
app.all('*',function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.setHeader('Access-Control-Allow-Credentials', true);
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
next();
I am trying to access the content from the URL using $http in client side:
//Controller.js
$http.get('http://domainA.com/a/ipadapi.php?id=135&client=ipad').success(function(response){
alert("I got response");
});
It's showing the following error in console.
XMLHttpRequest cannot load http://domainA.com/a/ipadapi.php?id=135&client=ipad The 'Access-Control-Allow-Origin' header has a value 'http://example.xxxxx.com' that is not equal to the supplied origin. Origin 'http://localhost:3000' is therefore not allowed access.
Note:I am new to nodeJS,Express and AngularJs
When you are passing credentials with CORS, you need to lock down the accepted origins. Try changing your origins from * to "localhost:3000"
See cross origin resource sharing with credentials
Change the header info from
res.setHeader("Access-Control-Allow-Origin", "*");
TO
res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
If you're not the owner of domainA then you cannot send CORS headers from that domain. You can use your Node server as middleware, and proxy the request from your server to domainA. Your server can send CORS headers back to your angular app. pseudo code with hapi and needle:
import Hapi from 'hapi'
import needle from 'needle'
const server = new Hapi.Server()
server.connection({
port: 9090
, routes: {
cors: true
}
})
const handler = (req, reply) => {
const url = 'https://domainA.com'
, data = {
body: 'code'
}
needle.post(url, 'body=${data.body}', function(err, res) {
let json = JSON.parse(res.body)
reply(json.data)
})
}
server.route({
method: 'GET',
path: '/route/{id}',
handler: handler
}
)
server.start( err => {
if( err ) {
console.error( 'Error was handled!' )
console.error( err )
}
console.log( 'Server started at ${ server.info.uri }' )
})

Categories