post request not receiving a body - node.js

I setup a post request from a js file like so:
fetch('/account/signup', {
method: 'POST',
body: JSON.stringify({ username: document.getElementById('username').value, password: document.getElementById('password').value, email: document.getElementById('email').value, startingBal: document.getElementById('startingBal').value })
}).then(response => response.json());
}
and I have a router receiving the post request
const router = express.Router()
router.use(bodyParser.urlencoded({ extended: true }))
router.use(bodyParser.json())
router.post('/signup', (req, res) => {
console.log(req.body)
})
Yet it only logs {} to the console, so it's receiving the request but doesn't log anything.

Add the header in your fetch config:
content-type: application/json
If it don't work, use postman and share the results

Related

Express server returning an empty body from a post request

I've been working on a project with express, and have a post request set up. However, it returns an empty body on the response, but it appears to be working otherwise.
Here's the server:
const express = require('express');
const app = express();
const http = require('http').Server(app);
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(bodyParser.raw());
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
app.use("/public", express.static(__dirname + "/public"));
http.listen(8080, '0.0.0.0' , function() {
console.log('listening on localhost:8080');
});
app.post('/form', (req, res) => {
console.log(req.body);
res.end('bla bla bla');
// I've also tried res.json and res.send
});
And here's the client:
fetch("/form", {method: "POST", headers: {'Content-Type': 'application/json'}, body: JSON.stringify({bla: "bla"})}).then((thing) => {
console.log(thing);
console.log(thing.json());
console.log(thing.body);
});
This seems like it should work, but instead it returns this object:
Response
body: (...)
bodyUsed: true
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
url: "http://localhost:8080/form"
[[Prototype]]: Response
I can't seem to find where the error lies, or even whether it's working and I just don't know how to get the data from it.
I've figured it out! It turns out that my code was working all along, it's just that I had messed up the fetch request. What I should have done client-side was:
fetch("/form", {method: "POST", headers: {'Content-Type': 'application/json'}, body: JSON.stringify({bla: "bla"})})
.then(res => res.json())
.then(data => console.log(data));
I was missing the second .then() and that was throwing it off.

Why does the csrf check not work on the server?

const csrfProtection = csrf({
cookie: {httpOnly: true}
})
// Middleware
app.use(express.json())
app.use(cookieParser())
app.use(csrfProtection)
app.use(cors({
origin: 'http://localhost:8081',
credentials: true,
methods: ['GET', 'POST', 'PUT', 'DELETE'],
exposedHeaders: 'XSRF-TOKEN'
}))
app.use(helmet.frameguard({ action: 'SAMEORIGIN' }))
app.use(helmet.ieNoOpen())
app.use(helmet.hidePoweredBy())
app.use(safetyMiddleware)
app.use('/api', router)
app.use(errorMiddleware)
I made a route that every time I visit the site, it sends a token in the request header
router.get('/', (req, res) => {
const xsrf = req.csrfToken()
res.set("XSRF-Token", xsrf).json('true')
})
Client axios:
Example:
const $host = axios.create({
withCredentials: true,
baseURL: process.env.VUE_APP_SERVER_URL,
headers: {
"xsrf_token": localStorage.getItem('csrf')
}
})
export const csrfAuth = async () => {
const {headers} = await $host.get('/')
localStorage.setItem('csrf', headers['xsrf-token'])
return headers
}
export const loginPassword = async (email, password) => {
const {data} = await $host.post('/user/login', {email, password})
return data
}
The first request comes in and saves one token in cookies, the second in local storage.
The first question is, should they be different?
Why does the server respond to a request to log in with a 500 status? The process doesn't even get to the next middleware
Thanks.
The statement
localStorage.getItem('csrf')
is executed only once when the browser reads the client-side javascript, that is, before csrfAuth() is called and the statement
localStorage.setItem('csrf', headers['xsrf-token'])
executed. Therefore the xsrf-token header in $host does not have the desired value when the POST /user/login request is made.

Post request in express in not accepting request body

I tried everything to get my request body in POST method. I'm using postman with raw and form-data mode. Tried calling this API from react too nothing works. console.log(req.body) prints blank. {}
do let me know what I am missing.
const express = require('express');
const app = express();
const bodyParser = require("body-parser");
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
const port = 9000
const enableWs = require('express-ws');
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.post('/', (req, res) => {
console.log(req.body);
res.send('Hello World!')
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
});
Now, I recreated your app, and it actually works.
I am using insomnia to test your api.
To the route "/" with Post, and some JSON.
Then in the Console.log I get the request body.
Console.log
Maybe you are testing incorrectly? Please get back to me if there is any question.
My guess is that you are not passing anything in your POST request, hence the empty body.
Be sure to specify Content-Type to application/json in postman's request headers.
In order for body-parser to parse req.body from JSON, your request must specify that the content is, in fact, JSON. Otherwise, it will not parse it; resulting in your blank req.body.
fetch('http://localhost:9000', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: 'hi',
}),
})

Can't find the request body on my POST request

I am using Node and Express to handle my back-end requests. I make a call from the front end:
const newData = {id: sub, first_name: given_name, last_name: family_name, email: email}
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newData)
}
fetch(`/add`, requestOptions)
.then(res => res.json())
.then(data => console.log(data))
.catch(console.log('error2'));
which get picked up by my "/add" end-point. For now I just want to console.log the request body so my end point is:
router.post('/add', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
console.log(req.body, 'hit')
})
However the server console log comes out as {} 'hit'. When I use the network tab I can see that the request has a payload containing id, first_name, last_name, and email.
Could anyone tell me what I am missing to get my data into my server.
Also my server is set up with body-parser like this:
const bodyParser = require('body-parser');
const app = express();
app.use(
bodyParser.urlencoded({
extended: false,
})
);
As you are sending an application/json content type, you should use bodyParser.json() instead of bodyParser.urlencoded({ extended: false }).
Ex:
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json())

reCAPTCHA with node.js and express

Building an app with node.js and express and want to implement reCAPTCHA.
My code is the following:
const app = require('express')();
const bodyParser = require('body-parser');
var request = require('request-promise');
app.use(bodyParser.urlencoded({ extended: false }))
app.post('/jow', (req, res, next) => {
console.log(req.body['g-recaptcha-response']);
var options = {
method: 'POST',
uri: 'https://www.google.com/recaptcha/api/siteverify',
body: {
secret: '6LcAuUoUAAAAAH-uiWl9cz0Wicg7iUsDxHImrgLO',
response: req.body['g-recaptcha-response'],
},
json: true // Automatically stringifies the body to JSON
};
request(options)
.then((response) => {
console.log(response);
})
.catch((err) => {
console.log('error');
})
});
I get the following output when I verify the CAPTCHA and send the form:
The errors state that I have a missing input response (while I have the token as we can see logged out) and a missing input secret. This indicates that something went wrong in the http request send using the request-promise package. What am I doing wrong here?
I know it's been a long time since the question, but, for future references, here's the solution.
The problem is with the body key:
body: {
secret: RECAPTCHA_SECRET,
response: req.body['g-recaptcha-response']
},
When using request-promise module and recaptcha, you should use the form key instead.
form: {
secret: RECAPTCHA_SECRET,
response: req.body['g-recaptcha-response']
},
Reference: https://github.com/request/request-promise#post-like-html-forms-do

Resources