How to dynamically skip express csurf based on form data? - node.js

I have a third party who wants to send a form via POST to my website to preset some inputs.
A POST is also used to finalize the form and process data when all fields have been provided.
The form should be CSRF-protected when the user submits it and data is to be processed server-side but should skip CSRF token check when the third party initially sends some data.
What's a clean way to bypass CSRF verification based on the data sent to a specific route and HTTP verb/method when using csurf?
One way I see is to work around this by using different route endpoints, but is there a more direct solution?

You may find you answer in here: Calling a middleware from within a middleware in NodeJS/ExpressJS. The thing is to implement a middleware which would call the csrf middleware in conditions match, or else directly call the next middleware with next().
Example:
app.use('my-route', (req, res, next) => {
if (condition) {
return csrfMiddleware(req, res, next);
} else {
return next();
}
});
If you want to use this middleware for a specific verb, replace app.use with app.<verb>. For example, app.get is pretty much a middleware checking for get verb.

Related

Whats the difference between a Controller and a Middleware

I am writing and API in express.js. the original API I wrote only utilized routes and raw SQL queries. I have since rewritten the API for the most part NOW using an ORM to react models and migrations.
My question what is the difference and use cases for middleware and controllers. currently only using middleware because most sources online online only explain what a middleware is.
I don't understand the use case of a controller. and I don't want to omit it from my API if its used in proper programming conventions
You should see middleware as a step in your API and controllers as the entity that will actually respond to the requests.
Bellow is an example where authenticationMiddleware is a middleware because it is a step during the processing but should not return the response. It can though, in case of error.
Then getItems actually handle the logic specific to this calls.
As a rule of thumb, middleware are often reused more than once and often they do not response. On contrary, controller respond and are most of the time specific to one endpoint.
const express = require("express");
const app = express();
function authenticationMiddleware(req, res, next) {
// Check that the user is authenticated using req.headers.Authorization
// for example
if (authenticated) {
// The user is authenticated, we can go to the next step
next();
} else {
// The user is not authenticated, we stop here
res.status(401);
res.send("Error during authentication");
}
}
function getItems(req, res, next) {
// Here we focus on the actual response, we assume that the user is authenticated
res.send({ items: [] });
}
app.get("/items", authenticationMiddleware, getItems);
app.post("/items", authenticationMiddleware, createItems); // Re-use the same middleware
app.listen(3000);
If you're referring to the node/express terminology, middleware are simply the callbacks used by the routing functions/methods (get, set, delete, use, etc). Callbacks can either send or not send responses back to the client. The callbacks are really the 'controllers' if you'd like to call them that (eg: ASP.NET Core MVC) but that's up to you. Below is a quote from Express. Note the term 'middleware' and where there's no mention of a 'controller'.
Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware
function in the application’s request-response cycle. The next
middleware function is commonly denoted by a variable named next.
Middleware functions can perform the following tasks:
Execute any code.
Make changes to the request and the response objects.
End the request-response cycle.
Call the next middleware function in the stack.
'Express' also defines different types of middleware which is useful:
Application-level middleware
Router-level middleware
Error-handling middleware
Built-in middleware Third-party middleware
Here's another nice look at it from Mozilla's pov that does mention a few controller/callback examples.
Beyond that, you can define what a 'controller' is within your team and the naming convention follows from there. Key is your SOLID profile and how you separate your concerns.

nodejs express wildcard route not working

I'm doing an API in nodejs with express as router.
Now i'm trying to implement an client-id and an apikey to add some security to the API, and the problem that i'm facing is the next:
One of my API call is like this:
router.get("roles/get-objects/:mail/:filter*?")
So this means, that i can request an object like this:
/roles/get-objects/mail#mail.com/customer
Now the tricky part begins... when I needed to stablish a middleware to read an client-id and an apikey to verify that the client is authorized to se the API, so I did this:
In the declaration of the middleware, I use this wildcard:
router.all('/*', function (req, res, next) {
XXXX})
The thing is, I have tried in the middleware, as a wildcard everything...
I want that any API call is filtered thru that middleware, but apparently I can't find the right wildcard for it...
When I use /roles/* as wildcard, if I do a request to /roles it does work, but when I use the complete URL like: /roles/get-objects/mail#mail.com/customer it doesn't go thru my middleware.
So anybody has any idea? i'm starting to loose my mind
Thank you so much to all of you!
EDIT:
Now i'm using this middleware declaration:
router.use(function (req, res, next) {XXXX})
So when I call:
/roles/get-objects/
It's executed, the problem is when I add the email to the route:
/roles/get-objects/mail#mail.com
The app goes directly to the route that i have for that, but omits my middleware:
router.get("roles/get-objects/:mail",
I don't understand why is this happening, apparently everything should go thru my middleware first, or am I wrong?
If you want to establish a middleware to check all HTTP request whose URL starting with /roles/, the middleware should be placed before any other specific router definition:
router.use('/roles', function(req, res, next) {...});
...
router.get('/roles/get-objects/:mail', ...);
If the middleware is defined after specific route, when HTTP request comes in, the specific route is targeted and processed, the middleware won't be executed any more:
router.get('/roles/get-objects/:mail', ...);
...
router.use('/roles', function(req, res, next) {...}); // This middleware logic won't execute when request is sent to '/roles/get-objects/some-email', as the request has already been handled and response is already sent to browser.

ExpressJS middleware vs logic

What is the best way to structure the logic in an ExpressJS API.
So lets say I want to create a register and login function, and lets say I want a user to be logged in when he is successfully registered.
Now there are different ways I can achieve this, my question is then essentially: Which method is best and why?
METHOD 1
Everything is middleware:
router.post('/path', someMiddleware, register, login, function(req, res){
//You are registered and logged in.
});
So here both the register and login is treated as middleware, with both of them ending with a call to next(). This also results in the best reusability, because I can call either login and/or register again in any other express routing.
METHOD 2
Register is middleware and calls login (which is now just a standard function):
router.post('/path', someMiddleware, register, function(req, res){
//You are registered and logged in.
});
So here register is still middleware, but just before calling next() it calls login() which in this case is not middleware. The problem here is that if user that is already registered wants to login, should I create a hybrid login function that is also middleware and just call it in that specific post request?
METHOD 3
Logic is not in middleware and gets called in the wrapper:
router.post('/path', someMiddleware, funcWrapper(register, login), function(req, res){
//You are registered and logged in.
});
and then (in pseudo):
funcWrapper(actions...){
foreach actions
action()
}
Here logic and middleware are split, there is a wrapper that loops through all the functions that are passed in as parameter (in this case register and login)
Just a last question:
If I haven't asked enough questions, I have a last one. Is it better practice to end all express routing calls with
..., function(req, res){
//response
});
or with
..., lastMiddleware);
and then in the lastMiddleware there is some response

How to push a sequence of html pages after one request using NodeJS and ExpressJS

I am turning around in stackoverflow without finding an answer to my question. I have used expressJS fur several days in order to make an access webpage that returns first an interstitial and then a webpage depending on several informations I can get from the requester IP and so on.
My first idea for the interstitial was to use this piece of code:
var interstitial = function(req, res, next) {
res.render('interstitial');
next();
}
router.get('/', interstitial, nextPage);
setting a timeout on the next nextPage callback function of router.get().
However it looks that I could not do that. I had an error "Error: Can't set headers after they are sent.". I suppose this is due to the fact that res.render already give a response to the request and in the philosophy of express, the next function is passing the req, res args for another reply to another function that possibly could do it. Am I right?
In that case, is there a way to give several answer, with timeout to one request? (a res.render, and after that in the next callback a rest.send...).
Or is this mandatory to force client to ask a request to give back another response? (using js on the client side for instance, or timers on client side, or maybe discussing with client script using socket.io).
Thanks
Not sure I fully understand, but you should be placing all your deterministic logic within the function of the handler you're using for your endpoint.
Kinda like so:
router.get('/', function(req, res){
var origin = request.origin;
if (origin == '11.22.33.44'){
res.send('Interstitial Page.');
}else{
res.send('Home Page');
}
});
You would replace the simple text responses with your actual pages, but the general idea is that once that endpoint is handled you can't next() it to secondary handler.

Routes chaining in express

I have a simple app, built with the help of node.js and express. This app has multiple routes and basic login/logout mechanics. I want all routes to redirect to a login form if the user is NOT logged in. This can be done by inserting auth checker lines into each route file.
The question is :
Is it possible to chain the routes to push all requests through login checker route and then pass it to the requested one without writing anything to existing route files?
E.g. existing routes are "/", "/upload", "/login", "/logout".
I want the request to get or post "/upload" to be first processed by "/login" route and then by "upload" route.
Yes, you can chain handlers in a route. Your handler definition should be like
routehandler(req, res, next){
//send response directly
//or call next to call the next handler
}
You can then put multiple handlers in the order you want:
app.get('/server', ensureAuthenticated, housekeeping, routes.server.get)
Here ensureAuthenticated and housekeeping dont send the response just call next(). The last one returns the resulting page.
Please see you would want a different handler than what you use for login. Login page would do authentication, rest pages should just check if the user is authenticated or not. The difference would be clear if you are using sessions.
The args for the route handlers are the same as that of middlewares. Those are :
(err, req, res, next) Error handlers
(req, res, next) Non-error handlers
A trivial variation of above is that next can be left out if it is the end function you want in callback chain. You cannot have other args apart from these. You can see the how they are called here (line 154).
A route consists of method, route-match and callback array. Like the middlewares the callback chain is executed sequentially for a specific route until response is returned or error is thrown.

Resources