Empty request body in server, Object object into DB - node.js

I'm using NodeJS+express and React. The request body's expected output is "tipologia", but it actually returns an empty object.
I have looked for similar questions (there a lot of them) but none of these is useful.
client:
function CreateStudyPlan(tipologia){
return new Promise((resolve, reject) => {
fetch((URL+'/PianoStudio'), {
method: 'POST',
credentials: 'include',
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(tipologia),
}).then((response) => {
if (response.ok) {
resolve(null);
} else {
// analyze the cause of error
response.json()
.then((message) => { reject(message); }) // error message in the response body
.catch(() => { reject({ error: "Cannot parse server response." }) }); // something else
}
}).catch(() => { reject({ error: "Cannot communicate with the server." }) }); // connection errors
});
}
server:
// set-up the middlewares
app.use(morgan('dev'));
app.use(express.json());
const corsOptions = {
origin: 'http://localhost:3000',
credentials: true,
};
app.use(cors(corsOptions));
const isLoggedIn = (req, res, next) => {
if(req.isAuthenticated())
return next();
return res.status(401).json({ error: 'not authenticated'});
}
app.post('/PianoStudio', isLoggedIn, async (req, res) => {
try {
await dao.createPianoStudio(req.body, req.user.id);
res.status(201).json(req.body);
} catch(err) {
console.log(err);
res.status(503).json({error: `Database error during the creation of piano di studi for user ${req.user.id}.`});
}
});
The problem is that req.body is empty and should not be ( i am expecting it to output part-time):
The insert into the DB shows that req.user.id is ok, while req.body is an empty Object:
--
2 WORDS ON REQUEST ID AND BODY:
req.body should be the
body: JSON:Stringify(tipologia)
from the client, while req.user.id is retrieved by the session through the isLoggedIn.
2 WORDS ON HEADERS:
At first i had
headers: {
'Content-Type': 'application/json',
But it gave me CORS error:
Access to fetch at 'http://localhost:3001/PianoStudio' from origin 'http://localhost:3000' has been blocked by CORS policy: 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.
So i changed the Headers to
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "*"
}
as
putting 'Content-Type': 'application/json', returns again CORS error.

You should try to define tipologia as an object, in the Client:
body: JSON.stringify({tip_str: tipologia})
While in your Server, you will retrieve your tipologia as follows:
dao.createPianoStudio(req.body.tip_str, req.user.id)

Related

Axios bad request status 400

I'm having this issue AxiosError: Request failed with status code 400
I checked the console and I test manually the url and It worked, so I don't know what's wrong, this code:
//file controller.js
//Set Create Session
exports.setSession = async (req, res) => {
const data = await request({
path: process.env.APP_LOCALHOST_URL + urlLogin.setCreateSession,
method: 'POST',
body: JSON.stringify(req.body)
});
return res.json(data);
}
//file request.js
exports.request = async ({path, method = "GET", body }) => {
try {
const response = await axios({
method: method,
url: path,
headers: {
'Content-Type': 'application/json'
},
body: body
});
return response;
} catch (error) {
console.log("error: ", error);
}
}
the function setSession is to call in my routes file, and the function request is my reusable component. My intention is to use the function request in many functions, these could be of the GET, DELETE, PUT, POST, PATCH type.
So, currently I get this on console:
data: {
error: '5',
errorId: 'badRequest',
errorString: 'Internal error: Undefined JSON value.'
}

cors policy error on express axios get method - error 503

I'm trying to pass throught cors policy using nodejs + express in an heroku api, but getting this error:
Access to XMLHttpRequest at 'https://....' from origin 'https://...' 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
My methods in the frontend are:
const fetchUser = async () => {
const res = await axios.get(
process.env.REACT_APP_API_URL + `/api/user/${userId}`,
{
headers: {
Authorization: `Bearer + ${token}`,
},
},
)
console.log(res.data)
setStatsInit({ waiting: false, stats: res.data })
}
in server:
const corsOptions = {
origin: true,
methods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'OPTIONS', 'DELETE'],
headers: [
'Content-Type',
'Authorization',
'application/json',
'text/plain',
'*/*',
],
credentials: true,
maxAge: 3600,
}
app.use(cors(corsOptions))
app.get('/api/user/:uid', middleware.decodeTokenContext, async (req, res) => {
const user = {
uid: req.params.uid,
}
const userStats = await FirestoreClient.getByPath(`users/${user.uid}`)
return res.json({ userStats })
})
The middleware, to check if it is authenticated:
async decodeTokenContext(req, res, next) {
let token = req.headers.authorization.split(' ')[1]
try {
const decodeValue = await admin.auth().verifyIdToken(token)
if (decodeValue) {
return next()
}
return res.json({ message: 'Não autorizado' })
} catch (e) {
return res.json({ message: 'Erro Interno' })
}
}
on the network, on browser, i got this error:
How to solve that error of cors?

Google Cloud Function CORS error when making POST request

I can't enable CORS in GCF, allUsers is enabled. Here's my code following this post recommandations
I make a POST call with fetch and JSON as body.
My server supposed to handle the request by performing a reCaptcha verification.
Then respond based on the reCaptcha score.
Thing is I can't even make the request, my server returns status 500.
Emails are sent when sent with 'mode : no-cors'.
exports.contactSendmail = (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
if (req.method === 'OPTIONS') {
/* handle preflight OPTIONS request */
res.set('Access-Control-Allow-Methods', 'GET, POST');
res.set('Access-Control-Allow-Headers', 'Content-Type, Accept');
// cache preflight response for 3600 sec
res.set('Access-Control-Max-Age', '3600');
return res.status(204);
}
const { message, token, email } = JSON.parse(req.body);
console.log(message, token, email);
// Load Node native HTTPS package
const https = require('https');
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const recapatchaKeys = {
secret: `myhiddensecretkey`,
response: token,
};
const urlPath = `/recaptcha/api/siteverify?secret=${recapatchaKeys.secret}&response=${recapatchaKeys.response}`;
const recaptchaOptions = {
hostname: 'google.com',
// port: 443,
path: urlPath,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': 0,
},
};
const reqRecaptcha = https.request(recaptchaOptions, (recaptchaResponse) => {
console.log(`reCaptcha statusCode: ${recaptchaResponse.statusCode}`);
recaptchaResponse.on('data', (d) => {
process.stdout.write(d);
const recapatchaRes = JSON.parse(d);
if (recapatchaRes.score > 0.7) {
const msg = {
to: process.env.CONTACT_EMAIL_RECIPIENT,
from: email,
subject: 'Nouveau contact',
text: message,
// html: "<strong>Its too simple to send mail</strong>"
};
//ES8
(async () => {
try {
await sgMail.send(msg);
res.status(200).send('Email sent');
console.log('Email sent !');
} catch (err) {
console.error('Error with Sendgrid' + err.toString());
}
})();
} else {
res.status(403).send('Forbidden to send Email');
console.log('Forbidden to send Email');
}
});
});
reqRecaptcha.write('');
reqRecaptcha.end();
};
Here's my front call
const response = await fetch(process.env.CONTACT_SENDMAIL_URL, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(emailBody),
});
Any help would be appreciated
As mentioned in the comments, you are not handling any authentication in there. The Documentation states that:
you can either deploy it with the --allow-unauthenticated flag, or use the Console to grant the Cloud Functions Invoker role to allUsers. Then handle CORS and authentication in the function code.
And in order to handle authentication for end users you can in your code you can follow the instruction in this other piece of documentation, which is quite detailed.

Proxy API request through Express return pending Promise instead of response

I am currently trying to work with the Atlassian Jira rest API. In order to not get a CORS error I go through the recommended route of not sending the request from the browser but proxy it through my express server.
Now as I am doing this, all I receive back in the app is a pending promise. I assume that I have not correctly resolved it at one point but I cant figure out where.
API Handler sending the request to the proxy:
const baseURL = `${apiConfig}/jiraproxy`;
export const testConnection = integration => {
return fetch(`${baseURL}/get`, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify(integration)
})
.then(handleResponse)
.catch(handleError);
};
Jira Proxy Endpoint on the Express Server
const baseURL = `rest/api/3/dashboard`;
router.post("/get", (req, res) => {
fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
.then(handleResponse)
.catch(handleError);
});
handleResponse & handle Error Methods:
async function handleResponse(response) {
if (response.ok) {
return response.json();
}
if (response.status === 400) {
const error = await response.text();
throw new Error(error);
}
throw new Error("Network response was not ok.");
}
function handleError(error) {
// eslint-disable-next-line no-console
console.error(`API call failed. ${error}`);
throw error;
}
Goal:
Send the request of sending a request to the proxy and return the resonse of the proxy as the return of the initial "testConction" method.
Error:
No errors thrown, but the response received in the Browser is a pending promise.
Change to the Jira Proxy router fixed it. Thanks to #jfriend00.
router.post("/get", (req, res) => {
return fetch(req.body.link + baseURL, {
method: "GET",
headers: { Accept: "application/json" },
auth: {
username: req.body.credentials.username,
password: req.body.credentials.token
}
})
// This is the part that changed
.then(response => handleResponse(response))
.then(jiraResponse => res.status(200).json(jiraResponse))
.catch(handleError);
});

EXPRESS : How to prevent Fetch() to repond with cached response

I am facing a very strange issue, I have a middleware where I am making a fetch() call to my API from my Express APP. it looks like :
Middlware Function
export function handler (req, res, next) {
if (someURL) {
return fetch(someURL, {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json'
},
credentials: 'include',
cache: 'no-store'
})
.then((response) => response.json())
.then((response) => {
log.info(`called response${response}`);
log.info(`called response status${response.status}`);
if (response.status && response.status === 'SUCCESS') {
res.clearCookie('master', { httpOnly: true, secure: true, domain: 'someDomain' });
return next();
}
throw Error(response.statusText);
})
.catch((error) => {
next(error);
});
}
}
here When I hit that URL that is intercepted with this Middleware, I want the cookie to be cleared and for that i am using the Header with the details above. But When I make this call I get the 200 OK from the disc written in the chrome network tab and call does not work properly as the cookie expiration headers coming from the APIs are not getting rendered. Can someone Point out what is wrong and how can I stop this caching in-order to get these cookies deleted?
thanks in advance

Resources