Reputation:
As an exercise in learning NodeJS, I am building a sort of API with ExpressJS that responds to web requests. As of right now, there are three routes in the program, '/login', '/register', and '/changePassword'. All of these methods do not need any sort of token to be processed.
However, every other route I plan to add to the program, (for example, a '/post' route) would require that the user authenticate themselves with a token obtained from a POST request to '/login' with the correct credentials.
TO verify the Token, I have written a middleware function:
module.exports.validateToken = function (req,res,next) {
const token = req.headers['x-access-token']
console.log(`validateToken() - TOKEN: ${token}`)
if (token) {
//Make sure the token is valid[...]
next()
}else {
return res.status(401).send({
message: 'Missing token',
success: false
})
}
}
My question is, how do I apply this middleware to only the routes that would require authentication? I've thought of just creating another Router object, and calling it like this:
const tokenValidator = require('./util').validate.validateToken
// Router used for any actions that require user-authentication
const authRouter = new app.Router()
authRouter.use(tokenValidator)
But would this interfere at all with my original, authentication free routes?
// Initiate the routes that don't need auth
const routes = require('./routes')(app)
Thanks in advance, I am more of a Java developer, so a lot of the Javascript quirks have left me stumped.
Upvotes: 16
Views: 14032
Reputation: 506
In Expressjs, every middleware you add, gets added to the middleware stack, i.e. FIFO.
Thus, if you have certain routes, which you'd like to have no authentication, you can simply keep their middlewares above others.
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use(<<pattern>>, authenticate)
Additionally, you can try using nodejs basic-auth module for authentication
Hope this helps!
Upvotes: 8
Reputation: 6472
Let's say your middleware is in "./middleware/auth"
I would create a base route for which the middleware should be applied, e.g.
app.use("/private", require("./middleware/auth"));
This will invoke your auth middleware, on any route which starts with '/private'
Thus, any API controller which requires auth should then be defined as:
app.use("/private/foo", require("./controllers/foo"));
Your middlware function will be invoked for any route within /private, before it hits your controller.
And any that do not require your middleware, should simply stay outside of the 'private' api context, e.g.
app.use("/", require("./controllers/somecontroller"));
Upvotes: 23