Cannot access to req.body inside middlewares - node.js

I actually have a very tiny app in node.js with Express, and I can't access to req.body.
This is my app.js code:
var express = require('express'),
middleware = require('./middleware'),
mysql = require('mysql'),
app = express();
app.use(middleware.authenticate);
app.use(middleware.getScope);
app.listen(3000);
module.exports = app;
And the file with the middlewares:
var bcrypt = require('bcrypt'),
mysql = require('mysql');
function authenticate(req, res, next){
console.log(req.body);
next();
}
function getScope(req, res, next){
console.log(req.body);
next();
}
module.exports.authenticate = authenticate;
module.exports.getScope = getScope;
In all cases req.body is undefined.
I'm sending data throw Postman with x-www-form-urlencoded protocol, in this case is a must.
Thanks!!

You need to add body-parser to express:
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
Check Request here http://expressjs.com/en/api.html
And perhaps a POST route could help too:
app.post('/', function (req, res, next) {
console.log(req.body);
res.json(req.body);
});

Related

req.body returns undefined - nodejs

When I put app.use(bodyParser.json()); below app.use('/api', require('./routes/api'))
req.body returns undefined. But if I put app.use(bodyParser.json()); above app.use('/api', require('./routes/api')); it returns correctly. So the question is why?
Here is my code:
index.js file
const express = require('express');
const app = express();
const bodyParser= require('body-parser');
app.use(bodyParser.json());
app.use('/api', require('./routes/api'));
app.listen(process.env.port || 3000, function(){
console.log('You are listening to port 3000');
});
api.js file
const express= require('express');
const router= express.Router();
router.get('/ninjas', function(req, res){
res.send({type: 'GET'});
});
router.post('/ninjas', function(req, res){
console.log(req.body);
res.send({type: 'POST'});
});
router.put('/ninjas/:id', function(req, res){
res.send({type: 'PUT'});
});
router.delete('/ninjas/:id', function(req, res){
res.send({type: 'DELETE'});
});
module.exports =router;
Thanks in advance!
We need body-parser middleware to read from req.body,
In Javascript code executes line by line (for non IO operations).
So when you place app.use(bodyParser.json()) after requiring your router file logic, body-parser is not invoked and plugged, so you need to invoke it before any other logic, so that you can read from the request.
Bodyparser is a middleware which should run everytime when a route is accessed.
A middleware (like bodyparser) is written like this
const middleware = (req, res, next) => {
//some code here
next();
}
The next function starts the execution of another middleware function
So when you use the bodyparser middleware after the routes req.body will not be initialized because the bodyparser middleware never ran for the route and the response ends with the res.send().
But if you use the bodyparser middleware before initializing the routes the bodyparser middleware will always run.
You can see more examples on middleware in the expressjs docs
https://expressjs.com/en/guide/using-middleware.html

How to access an API endpoint through a token using headers?

Currently I have a public api implemented, anyone can access it.
My intention is that the user now pass a token through the header so that they can access the data from the endpoints. But I don't know how to implement it in my code.
I appreciate your help!
router.get('/AllReports' , (req , res) =>{
PluginManager.reports()
.then(reports =>{
res.status(200).json({
reports
});
}).catch((err) =>{
console.error(err);
});
});
app.js
const express = require('express');
const morgan = require('morgan');
const helmet = require('helmet');
const cors = require('cors');
const bodyParser = require('body-parser');
const middlewares = require('./middlewares/index').middleware;
const api = require('./api');
const app = express();
app.use(morgan('dev'));
app.use(helmet());
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', (req, res) => {
res.json({
message: '🦄🌈✨👋🌎🌍🌏✨🌈🦄'
});
});
app.use('/api/v1', api);
app.use(middlewares);
module.exports = app;
To see a list of HTTP request headers, you can use :
console.log(JSON.stringify(req.headers));
Then you can check if token is valid and then
go on with processing.
Example
router.get('/', (req, res) => {
// header example with get
const authHeader = req.get('Authorization'); //specific header
console.log(authHeader);
// example with headers object. // headers object
console.log(req.headers);
});

Node.js and express : Routes

I have some trouble using the router from Express.
I want to set up my routes with several files.
I get my routes folder with 2 files: routes.js and inscription.js
I do the following
var inscription = require('./routes/inscription.js');
var routes = require('./routes/routes.js');
Then
app.use('/', routes);
app.use('/inscription', inscription);
But only the routes from routes.js work...
This is the content of routes.js
var router = require('express').Router();
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false});
//Homepage
router.get('/', function(req, res){
res.setHeader('Content-Type', 'text/html');
res.status(200);
res.render('home.ejs');
});
//Connexion
router.post('/connexion', urlencodedParser, function(req, res){
//Some content
});
module.exports = router;
And this is the content of inscription.js
var router = require('express').Router();
var hash = require('password-hash');
var db = require('../models/users.js');
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false});
router.get('/inscription', function(req, res){
res.setHeader('Content-Type', 'text/html');
res.status(200);
res.render('inscription.ejs');
});
router.post('/adduser', urlencodedParser, function(req, res){
var passwordHashed = hash.generate(req.body.inputPassword);
var newUser = {
nom : req.body.inputName,
email : req.body.inputEmail,
password : passwordHashed
};
db.addUser(newUser);
res.redirect('/');
});
router.post('/checkname', urlencodedParser, function(req, res){
var user = {
nom : req.body.inputName
};
db.checkName(user, function(length){
res.send(length);
});
});
router.post('/checkemail', urlencodedParser, function(req, res){
var user = {
email : req.body.inputEmail
};
db.checkEmail(user, function(length){
res.send(length);
});
});
module.exports = router;
The content of inscription.js works when it is pasted in the routes.js file ...
So I guess it is how I import the file that is not working.
Any idea?
This route router.get('/inscription', ...) in your inscription router is configured for the route /inscription/inscription which is likely not what you intended. This is because you've specified it in two places:
app.use('/inscription', inscription);
router.get('/inscription', ...)
So, the whole router is on /inscription from the app.use('/inscription', inscription). That means that any route the router itself defines will be added to that path.
It isn't exactly clear from your question exactly what you intend for the URLs to be. But, if you just want the above router.get() to work for a /inscription URL, then change:
router.get('/inscription', ...)
to:
router.get('/', ...)
When you use app.use('/inscription', inscription);, every single route in that router will be prefixed with /inscription. So, this route:
router.post('/adduser', ...)
will be mounted at:
/inscription/adduser
Or, if you want all the inscription routes to be at the top level too, then change:
app.use('/inscription', inscription);
to this:
app.use('/', inscription);
So that nothing is added to the path beyond what the router itself defines.

The JSON data in request body is not getting parsed using body-parser

When I send a POST request using postman to localhost:8080/api/newUser with request body:
{name: "Harry Potter"}
At server end console.log(req.body) prints:
{ '{name: "Harry Potter"}': '' }
server.js
var express = require('express');
var app = express();
var router = express.Router();
var bodyParser = require('body-parser');
app.use('/', express.static(__dirname));
router.use(function(req, res, next) {
next();
});
router
.route('/newUser')
.post(function(req, res) {
console.log(req.body);
});
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // support json encoded bodies
app.use('/api', router);
app.listen(8080);
What am I doing wrong?
In express.js the order in which you declare middleware is very important. bodyParser middleware must be defined early than your own middleware (api endpoints).
var express = require('express');
var app = express();
var router = express.Router();
var bodyParser = require('body-parser');
app.use('/', express.static(__dirname));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json()); // support json encoded bodies
router
.route('/newUser')
.post(function(req, res) {
console.log(req.body);
});
app.use('/api', router);
app.listen(8080);
Change the request header
'Content-Type':'application/json'
So that bodyParser can parse the body.
*That is what works for me. i am using angular 2+ with express(body-parser)
I spent quite a bit of time trying to figure out how to pass objects from Axios as key-value pairs and eventually decided to go with an alternative because setting the Content-Type: "application/json" retuned an empty object.
If the above options don't work for you, I would consider:
Extracting the key (which should contain the entire
object)
Parsing the key
Accessing the values of the newly created objects
This worked for me:
var obj = (Object.keys(req.body)[0])
var NewObj = JSON.parse(obj)
var name = apiWords["Key1"]
var image = apiWords["Key2"]

post using restler and node.js is not returning

I am trying to post using restler and return the response to client but response never returns .Below is code I am using and response is just hanging
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var rest = require('restler');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = 3001; // can also get it from process.env.PORT
var router = express.Router();
//this is like interceptor for every route to validate all requests, logging for analytics
router.use(function (req, res, next) {
console.log('route intercepted');
next(); // make sure we go to the next routes and don't stop here
});
router.get('/', function(req, res) {
res.json({ message: "welcome to restful node proxy layer to business processes" });
});
router.route('/someroute').post(function(req, res) {
rest.postJson('http://localhost/api/sg', req.body).on('complete', function(data, response) {
console.log(response);
}
).on('error', function(data, response) {
console.log('error');
});
});
app.use('/api', router); //all routes are prefixed with /api
app.listen(port);
console.log("server is running magic happens from here");

Resources