CORS blocking my node server from react app localhost - node.js

Tried everything I could find on here in regards to setting up cors for my node server. Tried aliasing my localhost and that doesn't seem to work either. Also tried using the CORS unblock extension.
error: localhost/:1 Access to fetch at
'http://localhost:8080/api/login' 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.
:8080/api/login:1 Failed to load resource: net::ERR_FAILED
im trying to use magic link authentication in my react app. I got this POST request being made to my node server
const res = await fetch(`http://localhost:8080/api/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + didToken,
},
});
my server code is
const express = require("express");
const cors = require("cors");
const { Magic } = require('#magic-sdk/admin');
require('dotenv').config();
const app = express()
const magic = new Magic(process.env.MAGIC_SECRET_KEY);
app.use("*", (req, res) => res.status(404).json({ error: "not found" }));
// Allow requests from client-side
app.use(cors({origin: process.env.CLIENT_URL}));
app.all('*', (req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Credentials', 'true');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept, Authorization'
);
res.sendStatus(200);
next();
});
app.post('api/login', async (req, res) => {
console.log("login fired")
try {
const didToken = req.headers.authorization.substr(7);
await magic.token.validate(didToken);
res.status(200).json({ authenticated: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = app

app.use(cors({origin: process.env.CLIENT_URL}));
I'd be curious what this URL is. If you want an open CORS policy you don't need to set anything any there.
Put a "/" in front of this route
app.post('/api/login', async (req, res) => {
I was able to reproduce your problem locally and this server setup worked for me to fix it.
const express = require("express");
const cors = require("cors");
const port = 8080;
const app = express();
app.use(cors());
app.post("/api/login", async (req, res) => {
console.log("login fired");
try {
res.status(200).json({ authenticated: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
module.exports = app;

Related

CORS on react request to node.js API

This is my node,js API,that works with no problems using postman, but when I try to make a request from a different origin like a react project the request is blocked
const express = require('express');
const mongoose = require('mongoose');
const app = express();
const port = process.env.PORT || 9000;
const routes = require('./routes/routes');
const token = require('./config/config');
const cors = require('cors')
app.use(cors())
app.use(express.json());
app.use('/api', routes);
app.listen(port, () => console.log('server listening on port', port));
const url = "mongodb://localhost/titles_db";
mongoose.connect(url,{})
.then( () => console.log('DB connected'))
.catch( (e) => console.log('Erorr on db connection'));
and this is the function that is called on my request
searchTitles = (req, res) => {
const terms = req.query.terms;
const format = req.query.format;
titleSchema.find({title: {$regex:terms, $options: 'i'}})
.then( data => {
if(format == 'json')
res.json(data);
else{
res.setHeader("Content-Type", "text/plain");
res.send(data);
}
})
.catch( error => res.json( {message: error}))
}
and here is the function that makes the request on the frontend
const getFieldText = e => {
setTerm({term: e.target.value });
const url = `http://localhost:9000/api/titles/?terms=${e.target.value}&format=json`
fetch(url)
.then(response => console.log(response))
.then(data => console.log(data));
}
even including cors library on node
const cors = require('cors')
app.use(cors())
I get this response
Response { type: "cors", url: "http://localhost:9000/api/titles/?terms=aaaaaa&format=json", redirected: false, status: 403, ok: false, statusText: "Forbidden", headers: Headers, body: ReadableStream, bodyUsed: false }
I added an options array but I have the same result
var corsOptions = {
origin: 'http://localhost:3000',
optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204
}
app.use(cors(corsOptions))
configure the cross headers like this (in your server node config):
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', "http://localhost:8080");
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, authorization, Access-Control-Allow-Origin');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', 'true');
// Pass to next layer of middleware
next();
});

react app express server CORS request did not succeed

I am trying to connect my front end to my back end, and I am using express server with node and react.
this is my fetch request fom front end: server runs on port 5000
const response = await axios.post("http://localhost:5000/send-email", {
to_email: data.data.email,
url: data.data.url,
});
console.log(response);
this resutls in:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8000/send-email. (Reason: CORS request did not succeed). Status code: (null).
I have in my back end:
app.post("/send-email", async (req, res) => {
try {
const { to_email, url } = req.body;
console.log(to_email, url);
await sendMail()
.then((result) => console.log("Email sent...", result))
.catch((error) => console.log(error.message));
res.send({ express: "YOUR EXPRESS BACKEND IS CONNECTED TO REACT" });
} catch (error) {
console.log(error);
res.status(500).json({ message: error });
}
});
I am also using core and also something like this:
// app.use(function (req, res, next) {
// // res.header("Access-Control-Allow-Origin", "*");
// res.header("Access-Control-Allow-Origin", "http://localhost:3000");
// res.header(
// "Access-Control-Allow-Headers",
// "Origin, X-Requested-With, Content-Type, Accept"
// );
// res.header("Access-Control-Allow-Methods", "POST, OPTIONS");
// res.header("Access-Control-Allow-Credentials", true);
// next();
// });
but regards less I keep getting this error and I am not sure how to get rid of it. I have seen several solutions they are either old, and I have tried some of them, they dont work at all.
Install cors using (npm install cors).
In your backend code file, add
var cors = require('cors') <br />
app.use(cors())
Alternatively, follow instructions given at https://www.npmjs.com/package/cors.
I fixed it like the following:
in my front end, I have
const response = await axios.post("http://localhost:8000/signup", {
newUserNameEmail,
url,
});
console.log("response--> ", response.data);
and in my backend server:
const PORT = 8000;
const express = require("express");
const cors = require("cors");
const nodemailer = require("nodemailer");
const { google } = require("googleapis");
const app = express();
app.use(cors());
app.use(express.json());
//sign up
app.post("/signup", async (req, res) => {
try {
const { newUserNameEmail, url } = req.body;
console.log(newUserNameEmail, url);
await sendMail(newUserNameEmail, url)
.then((result) => console.log("Email sent...", result))
.catch((error) => console.log(error.message));
res.status(200).json({ newUserNameEmail, url });
} catch (error) {
console.log(error);
res.status(500).json({ message: error });
}
});
So for some reason, this works and doesn't generate the error I was getting before. I can now communicate with front end and backend and send data, and email.
But I have no idea why this worked and the other one didnt. I also didnt change my package.json
Add proxy in your package.json file to the port of your backend api
"proxy": "http://localhost:8000"
then change your url in the request to port 3000 or wherever your frontend is
const response = await axios.post("http://localhost:3000/send-email", {
to_email: data.data.email,
url: data.data.url,
});
console.log(response);
proxy only works in local, however your app and api usually share the same main domain so this cors error will not appear in production..

CORS error when using Cloud Functions for Firebase

This is my first question posed, so I apologize if it is not formatted well.
I have been trying to figure out how to deal with the following CORS error, as well as, the CORS preflight error:
...has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header has a value 'https://example.com/' that is not equal to the supplied origin.
I have spent the last few days reading every question on this topic, and all other documentation I could find on CORS/Cloud Functions/Axios/etc. I am using React, Node, Express, Axios, Google Firebase to host, and Google Cloud Functions.
I am trying to access the PayPal API to gain a bearer token to make further API requests. I understand some of the code pertaining to the request headers might be redundant. I have just been trying to throw anything at this.
Does anyone have any ideas?
The node file - index.js
const axios = require("axios");
const express = require("express");
const cors = require("cors")({ origin: true });
const app = express();
app.use(cors());
app.use(express.json());
app.post("/v1/oauth2/token/", cors(), (req, res) => {
res.set("Access-Control-Allow-Origin", "https://example.com/");
var data = qs.stringify({
grant_type: "client_credentials",
});
var config = {
method: "post",
url: "https://api-m.sandbox.paypal.com/v1/oauth2/token/",
headers: {
"Access-Control-Allow-Origin": "https://example.com/",
Authorization:"xyz",
"Content-Type": "application/x-www-form-urlencoded",
},
data: data,
};
axios(config)
.then(function (response) {
let bearerToken = response.data.access_token;
res.status(201).send(bearerToken);
})
.catch(function (error) {
console.log(error);
});
});
exports.api = functions.https.onRequest(app);
The react file - payment.js
import axios from "../axios/axios";
const oneTimePaypalPayment = async () => {
const response = await axios.post("/v2/checkout/orders");
console.log(response);
};
The axios file - axios.js
import axios from "axios";
const instance = axios.create({
headers: {
"Access-Control-Allow-Origin": "https://example.com/",
"Access-Control-Allow-Headers": "https://example.com/",
},
baseURL: "https://us-central1-example.cloudfunctions.net/api/"
});
export default instance;
What I have tried
I have tried using the wildcard " * " just to try to get it to work but no luck. I read on another answer that Google Cloud Functions do not recognize the '*' anyways. I have also tried all of the code below, and a lot of other ways to manipulate the Access-Control-Allow-Origin on the request header
const allowCrossDomain = function (req, res, next) {
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
next();
};
app.use(allowCrossDomain);
app.all("*", (req, res, next) => {
res.header("Access-Control-Allow-Headers", "*");
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
next();
});
const corsOptions = {
origin: "https://example.com/",
};
app.use(cors(corsOptions))
app.options("/v1/oauth2/token", cors(corsOptions));
app.use(cors({origin:true}));
Any thoughts would be greatly appreciated
In a cloud function that you are exporting or working with use below for Origin :
exports.your function = async (req, res) => {
res.set('Access-Control-Allow-Origin', '*');

React Express Fetch Post CORS error: Response to preflight request doesn't pass access control check: It does not have HTTP ok status

I'm trying to set up a basic user signup form with React, Node, and Express, and using fetch. However, I'm getting the following errors in the Chrome console when I try and send a post request:
1) "OPTIONS http://localhost:7001/v1/register 500 (Internal Server Error)"
2) "Access to fetch at 'http://localhost:7001/v1/register' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status."
My eventual goal is to save the user's email and password in a database, but for now all I want is for the request to go through to the backend and have the backend log the body to make sure everything works. I've tried several different ways of setting headers, and I have no idea what's wrong. Below is the code.
Frontend form submit function:
handleSubmit(e) {
e.preventDefault();
const signUpInfo = this.state; // { email: 'test#gmail.com', password: '123' }
console.log(signUpInfo);
fetch('http://localhost:7001/v1/register', {
method: 'POST',
body: JSON.stringify(signUpInfo),
headers: {
'Content-Type': 'application/json'
}
})
.then(res => res.json())
.then(response => console.log('Success:', response))
.catch(error => console.error('Error:', error));
}
server.js
const express = require('express');
const compression = require('compression');
const cfg = require('config');
const path = require('path');
const logger = require('morgan');
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser');
const config = require('config');
const app = express();
app.use(compression());
app.use(bodyParser());
app.use(cookieParser());
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
res.setHeader('Access-Control-Allow-Credentials', true)
next();
});
// CONTROLLERS
const userController = require('./controllers/userController.js');
// ROUTES
app.post('/v1/register', userController.register);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
app.listen('7001', function() {
console.log('API server listening on port 7001!');
});
module.exports = app;
userController.js
exports.register = async (req, res, next) => {
try {
console.log(req.body);
res.status(200).json({ status: 200, data: req.body, message: "test" });
} catch (err) {
console.log(err);
res.status(500).json({ status: 500, data: null, message: err });
}
}
All I'm looking for is for the backend console to print out the body. It works with axios and $.ajax, but not with fetch. I've also tried using a proxy server to no avail (and would like to get it to work without a proxy).
Not sure if this is relevant, but I'm using Chrome as the browser and Sequelize.
Any help would be greatly appreciated. I feel like I'm missing something fundamental. Any helpful articles to deepen my learning would be a plus!
Instead of using
const app= express();
try to use
const app=express().use('*', cors());
and remove
app.use(function(req, res, next) {
res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,DELETE");
res.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Access-Control-Allow-Headers, Content-Type, Authorization, Origin, Accept");
res.setHeader('Access-Control-Allow-Credentials', true)
next();
});
see if this works.
First Install "cors":
npm i cors
Second import "cors":
cors = reqquire("cors");
Third use "cors":
const app = express();
app.use("*", cors());

CORS issues even after using npm cors plugin in node server

I have created a simple server in node js to take the request from a react app.
But for the GET method there is no CORS error but whenever I do post, it gives me an error.
For the POST method to work, I have implemented in index.js file of the actions folder and it should hit the url from the server.js file.
index.js
import axios from 'axios';
export const GET_NAVBAR = "GET_NAVBAR";
export const LOGIN = "LOGIN";
export const BASE_API_URL = "http://localhost:3030";
export const GUEST_API_URL = "https://XXX.XXX.XXX.X:5443/wcs/resources/store/1";
export const getNavbar = () => {
return axios.get(BASE_API_URL + '/topCategory').then(res => {
return {
type: GET_NAVBAR,
payload: res.data.express.catalogGroupView
};
});
};
export const login = () => {
return axios.post(GUEST_API_URL + '/guestidentity', {}).then(res => {
console.log(res);
return {
type: LOGIN,
payload: {}
}
}).catch(e => {
console.log(e);
return {
type: LOGIN,
payload: {}
}
});
};
server.js
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const Client = require('node-rest-client').Client;//import it here
const app = express();
const helmet = require('helmet');
const morgan = require('morgan');
// enhance your app security with Helmet
app.use(helmet());
// use bodyParser to parse application/json content-type
app.use(bodyParser.json());
app.use(cors());
// log HTTP requests
app.use(morgan('combined'));
app.post('/guestidentity', (req, res) => {
var client = new Client();
// direct way
client.post("https://XXX.XXX.XXX.X:5443/wcs/resources/store/1/guestidentity", (data, response) => {
res.send({express: data});
});
});
const port = 3030;
app.listen(port, () => console.log(`Server running on port ${port}`));
I don't know where my code is getting wrong. Can anybody please help me to troubleshoot this issue. I would be grateful if someone could provide an insight or guide me a little. Thanks
For my part I used
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");
next();
});
It will accept from any * sources, you might want to change that later
In your server.js , add the following middleware.
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'http://localhost:3030/');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
};
app.use(allowCrossDomain);

Resources