reCAPTCHA with node.js and express - node.js

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

Related

post request not receiving a body

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

Using axios to execute a post request in nodejs but I am not able to receive data in the post route

I am trying to execute a post request using axios but the req.body is showing empty object . Here is my code :
const postData = {
tournamentId: tournamentId,
category: category,
contestantId: contestantId,
};
axios.post(`${process.env.URL}/joinTournament`, postData)
.then((res) => {
console.log(`Status: ${res.status}`);
console.log("Body: ", res.data);
})
.catch((err) => {
console.error(err);
});
Try a few things like test your backend logic with Postman (An API Development Tool). Then try to console log your request in backend to confirm the request reaching is correct.
If all that checkout turn to your libraries if you are using expressjs try to use a middleware like body-parser and cors to send back responses
The Code being something like
For Cors
//Cors
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
app.get('/products/:id', function (req, res, next) {
res.json({msg: 'This is CORS-enabled for all origins!'})
})
app.listen(69, function () {
console.log('CORS-enabled web server listening on port 80')
})
For Body-parser
//body-parser
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }))
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' })
Might as well setup a checker block where you'd check that if the request is missing some necessary info to send back some understandable response.
I have solved this issue using qs and calling stringify method on postData . Here is my solution :
const qs = require("qs");
const postData = {
tournamentId: tournamentId,
category: category,
contestantId: contestantId,
};
axios.post(`${process.env.URL}/joinTournament`, qs.stringify(postData))
.then((res) => {
console.log(`Status: ${res.status}`);
console.log("Body: ", res.data);
})
.catch((err) => {
console.error(err);
});
if your server works very well with request from postman and every things is Ok, you can do like this, without third party module

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())

Issues with nodejs' request and pipe

I'm having an issue with the following code. I'm trying to make a POST request (json) to a URL using pipe but I get the error "write after end" - Internal Server Error. Can someone please help?
test: function( req, res, next) {
var requesty = request.post({
url: dataUrl,
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
});
req.pipe(requesty).on('error', function (error) {
logger.withRequestLog(res, 'error', 'CC Melville Proxy failed!', {
assetUrl: dataUrl,
error: error,
});
next(error);
}).pipe(res);
}
You are getting error because of body: JSON.stringify(body). You can't (also don't need) to pass body as when you are piping raw bytes are being piped as well. Also This middleware should be FIRST as you don't want to use bodyParser etc which will read the stream and make it empty.
Below is an working example where I am proxying my request to one my routes(It can be external also):
const express = require('express');
const app = express();
const request = require('request');
const bodyParser = require('body-parser').json();
const dataUrl = '/employees'
app.use(dataUrl, bodyParser, (req, res)=>{
res.json({
body: req.body || {},
method: req.method,
param: req.params,
headers: req.headers,
url: req.url
});
})
app.use('/', (req, res) => {
var requesty = request({
url: 'http://localhost:8080'+dataUrl,
headers: {
'Content-Type': 'application/json'
},
})
req.pipe(requesty).on('error', function (error) {
console.log('error', 'CC Melville Proxy failed!', {
assetUrl: dataUrl,
error: error,
});
}).pipe(res);
});
app.listen(8080, () => {
console.log('started');
})
Note: You don't need to specify method as it will automatically be passed. From the doc:
You can also pipe() from http.ServerRequest instances, as well as to
http.ServerResponse instances. The HTTP method, headers, and
entity-body data will be sent.

Express JS is receiving an empty req.body from ReactJS

I am currently having a problem with React and Express JS form submit function. It seems like my nodeJS running on port 5000 is receiving an empty object from my ReactJS running on port 8080 using fetch method.
React : Contact.js
handleSubmit(e)
{
e.preventDefault();
var data = {
name: this.state.name,
contact: this.state.contact,
email: this.state.email,
message: this.state.message,
}
var url = 'http://localhost:5000/api/insertUsers';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
mode: 'no-cors',
body: JSON.stringify(data),
})
.catch((error) => {
console.log(error);
});
}
NodeJS : server.js
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
app.listen(5000, () => {
console.log('listening on port 5000');
});
Change the order of bodyparser middleware like this.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
You are sending a request with the content-type of 'application/json' but express is expecting a content-type of 'text/json'. Usually, when req.body is empty content-type is the first suspect you should be looking at.
I am ashamed that I struggled with this for hours. I still haven't gotten it to work with file uploads.
But I did get it to work with a normal form by encoding JSON and sending that along with axios, instead of fetch
My js code
var data = {
id: this.state.id,
}
console.log('data',data)
var bodyFormData = new FormData();
bodyFormData.set('id', this.state.id);
var url = ' http://localhost:3000/get-image-by-id';
console.log("bodyFormData: ", bodyFormData);
axios({
method: 'post',
url: url,
data: data,
// headers: {'Content-Type': 'multipart/form-data' }
headers: {'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
Form Code
<form method="POST" onSubmit={this.handleSubmit} >
<label>
Transaction ID
<input
type="text"
name="id"
value={this.state.id}
onChange={this.handleInputChange}
/>
</label>
<button type="submit">Submit</button>
</form>
```
EDIT
fetch(url, {
method: 'POST',
body: JSON.stringify(data),
mode: 'no-cors'
}).then((result)=>{
console.log("output" + result.json());
})
.catch((error) => {
console.log(error);
});
EDIT 2
for backend, install cors and add the following lines before route.
var cors = require('cors')
app.use(cors())
EDIT 3
perform npm install morgan then copy these lines inside the code
var morgan = require('morgan');
app.use(morgan('dev'));
I didn't look at your code close enough. My bad
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
Should be
app.post('/api/insertUsers', function(req, res) {
res.json(req.body)
});
try using axios instead of fetch
I rewrote ur code like this and it works perfectly
server
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
const cors = require("cors");
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/api/insertUsers', function(req, res) {
// console.log(req);
console.log(req.body);
res.send(req.body);
});
app.listen(3001, () => {
console.log('listening on port 3001');
});
react (ensure you have axios installed)
handleSubmit(e){
e.preventDefault();
var data = {
name: "zadiki",
contact: "0702002109",
email: "zadiki",
message: "test",
}
console.log("wow");
var url = ' http://localhost:3001/api/insertUsers';
axios.post(url,data)
.then(response=>console.log(response))
.catch(e=>console.log(e))
}
Hello I ended up getting mine working after I ran into the same problem.
I noticed your react code has "mode: 'no-cors'," that was causing problems with mine so I removed it.
-------- Below is my handle submit code for React ------------
const handleSubmit = (event) => {
event.preventDefault();
const url = "http://localhost:3001/register"
const options = {
method: "POST",
body: JSON.stringify(formData),
headers: {
"Content-Type": "application/json"
}
}
fetch(url, options)
.then(res => res.json())
.then(res => console.log(res))
}
I used express.json instead of bodyParser. You also had a typo in your express code, it should say res.send instead of res.end
--------- Below is my Node Express Code -----------
const express = require('express');
const app = express();
const cors = require('cors');
const multer = require('multer');
// Middlewares
app.use(cors({ origin: 'http://localhost:3000', }))
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(multer().array());
app.post('/register',(req, res) => {
console.log(req.body)
res.status(200)
.json({status:"Success", data:{body: req.body })
});
app.listen(3001, () => console.log(`Running on 3001`))
I was able to send form data using postman and react using the code above. Feel free to change it to accommodate your needs.

Resources