Exception CSRF check for routers node js - javascript

I am using webook to call one of my routers in my node js application.
I want to not use 'csurf' which is a library for CSRF token when that specific router is called.
The router is called ch and it is not the index router
My code for the CSRF expection is like this
var csrf = require('csurf');
var csrfProtection = csrf();
var csrfExclusion = ['/check-ch'];
var conditionalCSRF = function (req, res, next) {
if(csrfExclusion.indexOf(req.path) !== -1){
next();
} else {
csrf(req, res, next);
next();
}
}
router.use(conditionalCSRF);
router.post('/check-ch',(req, res, next) => {
console.log(req.body);
console.log('i am here');
});
Normally I searched stackoverflow but all answer shows that the method above should work but in my terminal I end up getting invalid csrf token, and I am not sure why.
The CSRF token is also being used in the index.js router, by the same method, where I load it first and then directly use router.use(csrfProtection), no conditionalCSRF is being used.
It looks like the conditionalCSRF is not even getting called, when I try to use a webook, so I am not sure what is stopping it to run.

Related

Function between route and route handler is not executing as expected

I am trying to write API's of which some of them has role based authorization. Further I am using JWT for authentication for my API's.
Below is the code, I am trying to write. However, when I hit "/user/:email" endpoint, authorize function is not getting called. Always, getUser function is getting called. I was in an assumption that at first authorize function should be called followed by getUser.
Can someone enlighten me why authorize function is not getting called when I hit "/user/:email" endpoint? What wrong am I doing here? And how can I correctly handle this scenario?
var express = require('express')
var router = express.Router();
var expressJwt = require('express-jwt');
var authorize = function(role){
expressJwt({secret:'secretKey'}, (req, res, next) =>{
console.log('req.role is', req.role);
if(req.role === role){
next();
}else{
res.status(403).send({message: 'Unauthorized'});
}
})
}
var getUser = function(req,res,next){
res.status(200).send("Hello user");
}
router.get('/user/:email', authorize('Admin'), getUser);
authorize is called when the application starts up, not when you hit "/user/:email". Calling authorize('Admin') just returns undefined which will not cause the console.log being executed, neither when "/user/:email" is hit.
I think what you want to achieve is applying multiple callbacks sequentially to one route.
See here
So, authorize('Admin') should return a middleware (also called callback), such as:
return expressJwt({secret:'secretKey'}, (req, res, next) =>{...})

What javascript library sets the _parsedUrl property on a request object

I am working with node/express/passport/ looking at code that attempts to use a request like:
req._parsedUrl.pathname;
I cannot figure out where this variable is coming from. Is this a canonical variable name that is set in a common .js library? It doesn't seem exposed in any headers.
req._parsedUrl is created by the parseurl library which is used by Express' Router when handling an incoming request.
The Router doesn't actually intend to create req._parsedUrl. Instead parseurl creates the variable as a form of optimization through caching.
If you want to use req._parsedUrl.pathname do the following instead in order to ensure that your server doesn't crash if req._parsedUrl is missing:
var parseUrl = require('parseurl');
function yourMiddleware(req, res, next) {
var pathname = parseUrl(req).pathname;
// Do your thing with pathname
}
parseurl will return req._parsedUrl if it already exists or if not it does the parsing for the first time. Now you get the pathname in a save way while still not parsing the url more than once.
You can write a middleware to handle then set properties for req.
var myMiddleWare = function () {
return function (req, res, next) {
req._parsedUrl = 'SOME_THING';
next()
}
};
app.get('/', myMiddleWare, function (req, res) {
console.log(req._parsedUrl); // SOME_THING
res.end();
})
Express middleware document in here

NodeJS fill "req" from other function

I've got a NodeJS + Express Server setup with a router that looks like this:
app.route('/clients/:clientId)
.get(users.ensureAuthenticated, clients.read)
.put(users.ensureAuthenticated, clients.hasAuthorization, clients.update)
.delete(users.ensureAuthenticated, clients.hasAuthorization, clients.delete);
app.param('clientId', clients.clientByID);
My Problem is that users.ensureAuthenticated fills the req parameter with the current user req.user.
Basically it does this: req.user = payload.sub; (with some other background stuff)
Then the req.user is available in the following functions e.g. clients.update, but not in clients.clientByID.
I know I could execute users.ensureAuthenticated in clients.clientByID again, but this would execute the code twice and be extra load on the server, right? I guess there must be another way, but I couldn't find anything in the documentation of express.
I'd like to know how I can access the req.user in clients.clientByID without executing the code in users.ensureAuthenticated twice.
Based on your question, I assume you would like to execute users.ensureAuthenticated before clients.clientByID is executed. This can be achieved by using the app.use functionality. app.use handlers will get executed before the app.param and app.route handlers.
For example:
var express = require('express');
var app = express();
app.use('/user', function(req, res, next) {
console.log('First! Time to do some authentication!');
next();
});
app.param('id', function(req, res, next, id) {
console.log('Second! Now we can lookup the actual user.');
next();
});
app.get('/user/:id', function(req, res, next) {
console.log('Third! Here we do all our other stuff.');
next();
});
app.listen(3000, function() {
});

Node.js detect if a variable exists in req for every page a user goes to

More specifically, I have an auth system that uses passportjs and req.user is defined if the user is authenticated.
Right now my website only has about 5 pages, but it's growing, and at the top of every route, I check if req.user exists and I pass a true or false variable to the rendered template, and the template renders accordingly.
I messed around with things such as app.get("*") but I didn't end up finding anything good.
How could I check if req.user (or anything else that could exist within req...) exists -- when a user goes to any page of my website, without repeting code?
Progress:
Using this code in app.js:
app.use(function (req, res, next) {
// Using req.locals.isAuthenticated would be better, as it's automatically passed to every rendered templates.
req.context = {};
req.context.isLoggedIn = req.isAuthenticated();
// req.locals.isAuthenticated = req.isAuthenticated();
next();
});
app.use('/dashboard', dashboard);
and this in the routes/dashboard route:
router.get('/', function (req, res) {
res.render('dashboard', { isLoggedIn: req.context.isLoggedIn });
});
Works - I can then see if the user is logged in by doing for example {{ isLoggedIn }}.
However when I uncomment the req.locals line in the first code snippet, I get a 500 error.
Two things to note:
Usually when your application needs to do something for a bunch of different pages, you want to setup a middleware function via app.use
Express has a res.locals variable whose properties will be included in any rendered template
With the above points in mind, you can construct something like the following:
app.use(function(res, req, next) {
res.locals.isAuthenticated = typeof(req.user) !== 'undefined';
next();
});
You then supply your additional template variables when your routes call res.render. For example:
app.get('/about', function(res, req) {
res.render('about', { 'testValue': 14} );
});
Your template will have access to both isAuthenticated and testValue.
I recommend you put some middleware in place before your route handlers but after passport's.
app.use(function(req, res, next) {
// Create a `context` object for use in any view.
// This allows the context to grow without impacting too much.
req.context = {};
// Assign your flag for authenticated.
req.context.isAuthenticated = typeof req.user !== 'undefined';
// Let the next middleware function perform it's processing.
next();
});
Then you can render each view with the context.
app.use('/', function(req, res) {
res.render('index', req.context); // Context is passed to view for usage.
});
This is all untested code.
You can do it as is already mentioned here ,but in this case you are going to check completely every request. Maybe you have got / you are going to have some pages that don't require any authentification and in this case you have to make some statement that will skip auth for that particular page or you can use something like this:
function checkUser(req, res, next) {
req.userAuth = (req.user !== undefined);
next();
}
app.post("settings", checkUser, doSomething);
app.post("administration", checkUser, doSomething);
app.post("index", doSomething); // Doesn't require any authentification
Or you can straight a way redirect a user
function checkUser(req, res, next) {
if (req.user === undefined) {
res.redirect("/login"); // res.render
}
else {
next();
}
}

Require Authentication for directory (except one page) with Passport.js / Node.js?

I'm new to using Passport.js, but I find it's going pretty well so far. I'm using Passport with passport-local.
However, I want to require authentication for an entire directory excluding one page. So in my node server I'm serving up this direcory like so (using express):
app.use("/admin", express.static(__dirname + "/admin"));
And then I want to let the user hit /admin/login.html, so I wanted to do something like this:
app.get('/gb-admin/login.html', function(req, res){ });
Then I want to require authentication for the rest, so something like this:
app.get('/gb-admin/*', ensureAuthenticated, function(req, res){});
Here is my ensureAuthenticated function, for reference if it helps:
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/gb-admin/login.html')
}
How would I go about doing this? I've been generally sending things in infinite loops and causing the browser to timeout. Can anyone help?
The reason you're getting timeouts is because you can't have an empty route handler; at one point, you have to either return a response, or hand the request over the the next route handler/middleware.
That said, try this:
function ensureAuthenticated(req, res, next) {
if (req.path === '/gb-admin/login.html' || req.isAuthenticated()) {
return next();
}
res.redirect('/gb-admin/login.html')
}
app.get('/gb-admin/*', ensureAuthenticated, function(req, res, next) {
next();
});
// the static middleware needs to be declared after the route above, otherwise
// it will take precedence and ensureAuthenticated will never be called.
app.use("/gb-admin", express.static(__dirname + "/admin"));
I don't think there's a way to get it working with a separate route for the login page (unless you actually implement reading login.html and sending it back from without that routes handler), hence the check for it in the ensureAuthenticated middleware.
I wonder if it is your callback. Try:
app.get('/gb-admin/*', function (req, res, next) {
ensureAuthentication(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/gb-admin/login.html')
});
});

Categories