Preflight failing while adding Authorization header - React + Nodejs - node.js

I am trying to communicate with the nodejs server , "Preflight" getting failed while adding Authorization header , with out header i am able to connect with server. Screen shot for request header from browser development tool is added below
CORS added to the server.js
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Content-Type,Authorization");
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
next();
});
React JS - Axios Code
let params = {
"userId": userName,
"password": password,
"random": event.target.name,
"grant_type": "password"
};
var config = {
headers: {
'Authorization': 'Basic YXBwbGljYXRpb246c2VjcmV0',
'Content-Type': 'application/x-www-form-urlencoded'
}
}
[Axios.post('/oauth/token', params, config).then((response) => {
if (response.status === 200) {
if (response.data.querySuccess) {
console.log(response);
}
).catch((error) => {
console.log(error);
alert.error('Oops some error occured please check the data you have submitted');
});
}][1]

Related

Node.js Api throwing CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status

i am getting below error while consuming node.js function from my vue.js application.
Access to XMLHttpRequest at 'http://0.0.0.0:1081/sendsecondarysalesreport' from origin 'http://0.0.0.0:1050' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
Here is my Node.js code.
const cors = require('cors');
const router = express.Router()
router.use((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-Methods",
"GET, POST, PATCH, PUT, DELETE, OPTIONS"
);
next();
});
var corsOptions = {
"origin": "http://0.0.0.0:1050",
"methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
"preflightContinue": false,
"optionsSuccessStatus": 200
}
router.use(cors(corsOptions));
router.options('/*', (_, res) => {
res.sendStatus(200);
});
router.options('/sendsecondarysalesreport', cors(corsOptions));
router.post('/sendsecondarysalesreport', cors(corsOptions), (req, res, next) => {
try {
if (req.body.CustomerCode != "") {
SendSecondarySalesReport(req.body)
res.json([{ "CustomerCode": req.body.CustomerCode }]);
} else {
res.send({ "Status": false, "Error": "Not Found" })
}
} catch (error) {
console.log("error", error);
res.status(500)
res.send(error.message)
}
});
module.exports = router ;
Here is my client side code
this.$http.post(helper.URL() + 'sendsecondarysalesreport', formData, {
headers: {
'Content-Type': 'application/json'
}
}).then((response) => {
if (response.status == "200") {
}
Please help me solve the issue.
I have tried many solutions available here and every time the result is same. Its working fine in my development server but after hosting in iis this issue is coming.

React & Node.js fetch basic authorization

I am using fetch api to make request from reactjs to node.js backend with Basic Authorization with the code below...
React
fetch(baseUrl, {
method: 'get',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
authorization: 'Basic ' + secret,
},
}).then((res) => {
if (res.ok) {
return res.json();
} else {
return Promise.reject(res.statusText);
}
})
.then((resBody) => {
//
})
.catch((error) => {
console.error(error);
});
Node.js
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type, Authorization');
res.setHeader('Access-Control-Allow-Credentials', true);
return next();
});
app.use((req, res, next) => {
const base64Credentials = (req.headers.authorization || '').split(' ')[1] || '';
const [username, password] = Buffer.from(base64Credentials, 'base64').toString().split(':');
const auth = { username: 'username', password: '123456' }
console.log(username, password, auth.username, auth.password);
// comment below
if (username === auth.username && password === auth.password) {
return next();
} else {
res.status(401).send('Authentication required.'); // custom message
}
});
The following error is occur when I try to make the request.
Access to fetch at 'http://127.0.0.1:5000/' 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.
However, when I comment the comparison part in the second middleware if (username === auth.username && password === auth.password) it works fine. I have tried using Postman to send request it also no problem happen. The problem only occur when I make the request from react app. Anyone know what is the reason? Thanks a lot
it seems that the CORS npm is no installed npm i cors and write this code:
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
more information about CORS npm

cors request failed on vue/express

I'm running a vue app on an apache server on a virtual server. Express is started with nodemon.
When trying to login I'm getting a
Cannot read property 'status' of undefined xhr.js:160
POST https://143.93.46.35:60702/user/login net::ERR_TIMED_OUT
on chrome and
Cross-source (cross-origin) request blocked: The same source rule prohibits reading the external
resource on https://143.93.46.35:60702/user/login. (Reason: CORS request failed)
on firefox.
In vue my axios baseURL looks like (node is running on port 60702):
const apiClient = axios.create({
baseURL: `https://pvapp.umwelt-campus.de:60702`,
withCredentials: false, // This is the default
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
})
export default{
loginUser (user) {
return apiClient.post(`/user/login`, user)
},
...
}
And the user route on express is:
router.post('/login', async (req, res) => {
let compareUser = await db.query('SELECT * FROM app_users WHERE username=? LIMIT 1', [req.body.username]); // use db.query() to retrieve the password
if (compareUser.length < 1) // compareUser is an array with at most one item
res.sendStatus(403);
let valid = bcrypt.compareSync(req.body.password, compareUser[0].password);
if (!valid)
res.sendStatus(403);
let user = new User(compareUser[0]);
const token = jwt.sign({ user }, nconf.get('jwtToken'), { expiresIn: '14d' });
Object.assign(user, { token });
res.json(user);
});
In app.js cors is enabled like:
app.use(cors());
You need to res.setHeader('Access-Control-Allow-Origin', YourOrigin); in a middlewar before app.use(cors()); in order to allow the client.
EDIT :
You can do something like this :
router.use(function (req, res, next) {
let origin = req.headers.origin;
if (allowedOriginsTab.includes(origin)) {
res.setHeader('Access-Control-Allow-Origin', origin);
}
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});

'Access-Control-Allow-Credentials' header in the response is ' ' when trying to send a POST request to an API using Axios

I have a react app running in localhost:3000 and a nodeJS-express server on localhost:8000, I need to send a POST request to the jsreport API, but when I try to send the request I got the following error:
Access to XMLHttpRequest at 'http://localhost:5488/api/report' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Post request:
axios.defaults.withCredentials = true;
axios.post('http://localhost:5488/api/report',
{withCredentials: true, crossorigin: true},
{
"template": {
"content": "<h1>Hello {{foo}}</h1>",
"engine": "handlebars",
"recipe": "chrome-pdf"
},
"data": {
"foo": "world"
}
}).then((response)=> {
fs.writeFileSync('/reports/report.pdf', response.content)
}).catch(function (error) {
console.log('AXIOS error: '+ error);
return 'errorReport'
})
Server.js:
var corsOptions = {
origin: 'http://localhost:3000',
credentials : true
}
app.use(cors(corsOptions));
app.use((req, res, next) => {
res.header('Access-Control-Expose-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header("Access-Control-Allow-Origin", "http://localhost:3000");
res.header("Access-Control-Allow-Credentials", true);
res.header("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
const err = new Error('Not Found');
err.status = 404;
next(err);
})
I don't understand why the credentials are empty If I use .withCredentials in axios and established the headers and the cors configuration in the server.
I used the next code instead of the axios request and it worked:
fetch('http://localhost:5488/api/report', {
method: 'POST',
body: JSON.stringify(data),
headers:{
'Content-Type': 'application/json'
},
credentials: "same-origin",
}
Set credentials to "same-origin" fixed the problem, but as I wanted to use jsreport I found a package to make this easier without using fetch or axios.
import jsreport from 'jsreport-browser-client-dist'
jsreport.serverUrl = 'http://localhost:5488'
jsreport.render(document.getElementById('reportPlaceholder'), data)
Using the jsreport methods I could show my report in the react component
<div id="reportPlaceholder">
<p>there should be a report here...</p>
</div>
Update Server.js as below
var corsOptions = {
origin: 'http://localhost:3000',
credentials : true
}
app.use(cors(corsOptions));
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
res.setHeader('Access-Control-Allow-Credentials', true);
next();
});
i've been fiddling with persistent user sessions for a while and was having trouble stringing together passport / passport-local (for authentification), mongoose, express-session, and connect-mongo (for storing sessions in mongo).
#mshibl comment helped me get 1 step further, and setting these cors options for express finally had cookies being passed correctly. hopefully this helps someone else having a similar issue
app.use(cors({
credentials: true,
origin: "http://localhost:3000"
}));
This worked for me
export default function({ $axios, redirect }, inject) {
// Base URL
const base = process.env.API_URL
// Sett withCredentials on $axios before creating instance
$axios.defaults.withCredentials = true
// Create a custom axios instance
const api = $axios.create({
baseURL: base,
responseType: 'json',
timeout: 10000,
// withCredentials: true,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Content-Type': 'application/json'
}
})
// Inject to context as $api
inject('api', api)
setting the defaults.withCredentials before creating my own instance solved it for me.

CORS issue with Restify

I have created a ReactJs app with a Node Api which uses Restify, but whatever I do I always have the error for POST method :
405 (Method Not Allowed)
Access to fetch at 'http://localhost:3001/api/login' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
I have tried everything I saw on Internet but I always have this issue.
To call the API, here is my code :
const request = new Request(url + 'login', {
method: 'POST',
body: JSON.stringify({ 'username' : username, 'password' : password }),
headers: new Headers({ 'Content-Type': 'application/json' })
})
return fetch(request)
.then(response => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
}
return response.json();
})
.then(({ token }) => {
localStorage.setItem('token', token);
});
And I configure Restify like this :
const config = require('./config'),
restify = require('restify'),
errs = require('restify-errors');
var connection = config.db.get
const server = restify.createServer({
name: config.name,
version: config.version,
url: config.hostname
});
server.use(restify.plugins.acceptParser(server.acceptable));
server.use(restify.plugins.queryParser());
server.use(restify.plugins.bodyParser());
server.use(
function crossOrigin(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, OPTIONS, DELETE');
res.header('Access-Control-Allow-Credentials', false);
return next();
}
);
server.listen(3001, function () {
console.log('%s listening at %s', server.name, server.url);
});
server.post("/api/login", function (req, res) {
res.send(200);
});
So I expect to receive a validation (code 200) after calling the Api, but I always have CORS issue.
Is there anything else to configure ?
Thanks for your help !!! :D
You have to use corsMiddleware to avoid cors issue....write this code in your app.js file ...it should be work fine
var restify = require('restify');
var corsMiddleware = require('restify-cors-middleware');
var cors = corsMiddleware({
preflightMaxAge: 5,
origins: ['*'],
allowHeaders:['X-App-Version'],
exposeHeaders:[]
});
/**
* Initialize Server
*/
var server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);

Resources