Is there a way to intercept a http call before the csurf validation. I have the below code
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// create express app
var app = express()
// create api router
var api = createApiRouter()
// mount api before csrf is appended to the app stack
app.use('/api', api)
// now add csrf and other middlewares, after the "/api" was mounted
app.use(bodyParser.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(csrf({ cookie: true }))
app.get('/form', function (req, res) {
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', function (req, res) {
res.send('csrf was required to get here')
})
function createApiRouter () {
var router = new express.Router()
router.post('/getProfile', function (req, res) {
res.send('no csrf to get here')
})
return router
}
I want to log the CSRF token sent by the client for troubleshooting an error I am getting. But I was not able to find a way to intercept the request before it is sent for CSRF validation.
I was able to do it by adding the following code
var logToken = function (req, res, next) {
console.log('Token: ', res.get('x-xsrf-token');
next();
};
app.use(logToken);
I added this code before configuring the csrf token and after configuring the cookie parser.
Related
I am trying to read the body of POST request using Express in Node.JS framework. I send a HTTP POST request using HTML form. I detected a POST request on WireShark with the following data:
This shows that the request is sent successfully. I expected JSON format, which is the one that Express successfully parsed for me, but this format just doesn't seem to work no matter what I tried. My current implementation goes like this:
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var jsonParser = bodyParser.json()
//Import static files
app.use(express.static('../public'))
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/', jsonParser, (req, res) => {
console.log(req.body);
res.send(200);
});
app.listen(port, () => console.log("Server started"));
No matter what I try from other posts, it still does not seem to return me any data.
Does anyone have an idea how to fix this problem?
Why to you use 'jsonParser' in the app route? Try something like:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/post-test', (req, res) => {
console.log('Got body:', req.body);
res.sendStatus(200);
});
im trying to get the params of my post request. I can send them with JSON and it will work (if i take out the type property of the BodyParser.json) but not form data. Im using the body-parser middleware as follows.
const BodyParser = require('body-parser')
const Config = require('../config/environment');
const Express = require("express");
const App = Express();
App.use(BodyParser.json({type: '/', limit: '50mb'}));
App.use(BodyParser.urlencoded({extended: false}));
App.listen(3000, () => {Response.logger('Api running on port 3000.');});
App.post("/signup", (req, res, next) =>
{
consoleAlert('SIGNUP', false);
console.log(req);
Account.signup(req.params).then(
function(results) {response(results, res, 'SIGNUP');},
function(error) {response(error, res, 'SIGNUP');});
});
So when i print out req, the body is always empty with form data
Written from scratch - this appears to work:
server:
//app.js
const express = require('express');
const bodyParser = require('body-parser');
let app = express();
app.use(bodyParser.urlencoded({extended: false}));
app.post('/', function(req, res, next) {
console.log(req.body);
});
app.listen(3022);
client: call curl from command line sending form data (application/x-www-form-urlencoded is the default), mine node server IP is 10.10.1.40 :
curl -d "param1=value1¶m2=value2" -X POST http://10.10.1.40:3022/
In this example below, you can see that the csrfProtection and parseForm functions are passed as parameters/callbacks in the GET and POST requests...
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// setup route middlewares
var csrfProtection = csrf({ cookie: true })
var parseForm = bodyParser.urlencoded({ extended: false })
// create express app
var app = express()
// parse cookies
// we need this because "cookie" is true in csrfProtection
app.use(cookieParser())
app.get('/form', csrfProtection, function(req, res) { // HERE
// pass the csrfToken to the view
res.render('send', { csrfToken: req.csrfToken() })
})
app.post('/process', parseForm, csrfProtection, function(req, res) { // AND HERE
res.send('data is being processed')
})
However, if you are using a router, like I am, how can use these same functions? I am aware that by "using" them in app.js, they are made available on the req object but in the example given above, they are required as the 2nd and 2nd & 3rd arguments of the GET and POST routes, but req isn't made available until you're inside the final callback?!
So I know you can't do the below (just as an example)... so how should you use them? Would I have to re-declare them in every routes file?
Separate routes file: routes/someroute.js
...
router
.post('/', req.body, req.csrfProtection, (req, res) => {
})
...
Thanks in advance :)
Reference: https://www.npmjs.com/package/csurf
UPDATE
Following comments below, I have made the following changes to my app.js file.
app.js
...
global.bodyParser = require('body-parser').urlencoded({extended: false});
app.use(global.bodyParser);
global.csrfProtection = csrf({ cookie: false });
...
routes/myroute.js
router
.post('/', global.bodyParser, global.csrfProtection, (req, res) => {})
However, when I restart the server I am seeing this error, which suggests that that the global function is not defined... what am I missing here? :-/
Error: Route.post() requires a callback function but got a [object Undefined]
I think you ask about sharing middlewares across all API/routes files
You can do it like this :
First in your main file lets call it server.js we use you're code
var cookieParser = require('cookie-parser')
var csrf = require('csurf')
var bodyParser = require('body-parser')
var express = require('express')
// create express app
var app = express()
// setup route middlewares
app.use(bodyParser.urlencoded({ extended: false }))
// parse cookies
app.use(cookieParser())
//enable your JS API/route script.
const awesomeAPI = require('./awesomeApi.js');
app.use('/awesome', awesomeAPI );
app.listen(3000);
Now you have file let's calle it awesomeApi.js
const express = require('express');
const awesomeApi = express.Router();
awesomeApi.route('/')
.post(req,res => {
//req.body present here. And body parser middle ware works.
})
module.exports = awesomeApi;
Hope this helps.
Some links:
https://expressjs.com/en/guide/using-middleware.html
https://expressjs.com/en/4x/api.html#express
I have a basic server. One of my tests that I need to pass is to send the response header of 200. I added the code for the server as it is now. But not sure how to send response headers. Thanks for any help you may be able to provide!
var express = require('express');
var bodyParser = require('body-parser');
var Users = require('./models/users');
var app = express();
app.use(bodyParser.json());
// YOUR CODE BELOW
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var router = express.Router();
// middleware for all requests:
router.use(function(req, res, next){
console.log('we out here babay!');
// get to the next route and ensures we don't stop here.
next();
})
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
app.use('/api', router);
// Do not touch this invocation of the `listen` method
app.listen('8888', function () {
console.log('listening on 8888');
});
// Do not touch the exports object
module.exports = app;
Use res.status(CODE) method!
res.status(200).json({ message: 'hooray! welcome to our api!' });
As highlighted in comments by jfriend00, default status code is 200 so any regular response will already be 200 but for other codes like 500 or 404, if your client side is considering it while reading the response, you can use res.status() method.
I am developing an application using the MEAN stack (Node.js, Express, AngularJS, and Mongoose). I have a basic understanding of the two. My API is running on a different port from my frontend, and because of this, I've included the CORS header in my API file. However, Chrome is still giving me this error:
XMLHttpRequest cannot load http://localhost:9000/#/.
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access.
This is the header I've included in my API:
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
I have no idea where I'm going wrong. If it helps at all, I'm trying to load a user object in order to display information on a profile page. This is the code from my Profile Controller:
angular.module('angTestApp')
.controller('ProfileCtrl', function ($scope, $http) {
$http.get('http://localhost:8080/profile')
.success(function (user) {
$scope.user = user;
console.log(user);
});
});
EDIT
Here's my server.js file if that helps:
// server.js
// BASE SETUP
// =============================================================================
// call the packages we need
var express = require('express'); // call express
var cors = require('cors');
var app = express(); // define our app using express
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.connect('mongodb://test:test#novus.modulusmongo.net:27017/a3pemoGa')
var classroom = require('./app/models/classroom');
var article = require('./app/models/article');
var user = require('./app/models/user');
//From Tutorial
var passport = require('passport');
var flash = require('connect-flash');
var morgan = require('morgan');
var cookieParser = require('cookie-parser');
var session = require('express-session');
// configure app to use bodyParser()
// this will let us get the data from a POST
app.use(bodyParser());
app.use(cors());
//app.use(express.static(__dirname + '/public'));
var port = process.env.PORT || 8080; // set our port
// ROUTES FOR OUR API
// =============================================================================
// more routes for our API will happen here
// REGISTER OUR ROUTES -------------------------------
//From tutorial
// set up our express application
require('./app/config/passport')(passport); // pass passport for configuration
app.use(morgan('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser.json()); // get information from html forms
app.set('view engine', 'ejs'); // set up ejs for templating
app.use(session({ secret: 'ilovescotchscotchyscotchscotch' })); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
require('./app/API/routes')(app, passport);
//require('./app/API/general');
// START THE SERVER
// =============================================================================
app.listen(port);
console.log('Magic happens on port ' + port);
//exports = module.exports = app;
i resolved the cors issue with tricky solution . first create the the route of scrape like this with require "REQUEST" npm
app.get('/scrape', function (req, res) {
console.log("=============================Scrape =========================")
var url = req.body.url;
request(url, function(error, response, html){
if(!error){
res.send(html)
}
});
and in the frontend use like this
$http.get("/scrape", {
params: { "url": "http://localhost:8080/profile" }
});