Express.js Authentication
Now we will discuss how to implement authentication in Express.js. Express.js was discussed previously in the Introduction to Express.js. In the discussion there, we looked at how Express is a web-application framework just like CodeIgniter, Django, or Laravel except instead of running on something like Apache or Ngnix, it runs on Node.js and instead of being written in PHP or Python, it is written in JavaScript. Before looking at the following section, it might be a good idea to be familiar with Express.js by reading the introduction to Express and be familiar with Node.js as well. A Node.js Primer will help you with that.
When you think authentication in web development, you think logging in and logging out. Note that this is a little bit different from authorization, which has more to do with whether a logged in user has the permissions to do a certain action on a website. This the reason that you have different roles such as “Administrator,” “Editor,” and “User” defined within different systems. For this section we’ll focus more on authentication, but a lot of the ways that you handle authentication can also be extended upon to implement authorization.
Session-Based Authentication
When you speak of authentication in modern web applications, there are a number of different implementations you could be talking about. One of the more traditional approaches is the use of sessions. Sessions go back as far as anyone can remember with anything having to do with the web. Express.js supports sessions and you can use them just as you would in other languages like PHP.
Place the following code in a file called server.js. Obviously, in a real application we’d want to separate the markup we’re returning out into views and use a templating language to render them like we did in the introduction to Express. But for now, this will do just to serve for purpose of example…
var express = require('express');
var app = express();
app.use(express.bodyParser());
app.use(express.cookieParser('shhhh, very secret'));
app.use(express.session());
function restrict(req, res, next) {
if (req.session.user) {
next();
} else {
req.session.error = 'Access denied!';
res.redirect('/login');
}
}
app.get('/', function(request, response) {
response.send('This is the homepage');
});
app.get('/login', function(request, response) {
response.send('<form method="post" action="/login">' +
'<p>' +
'<label>Username:</label>' +
'<input type="text" name="username">' +
'</p>' +
'<p>' +
'<label>Password:</label>' +
'<input type="text" name="password">' +
'</p>' +
'<p>' +
'<input type="submit" value="Login">' +
'</p>' +
'</form>');
});
app.post('/login', function(request, response) {
var username = request.body.username;
var password = request.body.password;
if(username == 'demo' && password == 'demo'){
request.session.regenerate(function(){
request.session.user = username;
response.redirect('/restricted');
});
}
else {
res.redirect('login');
}
});
app.get('/logout', function(request, response){
request.session.destroy(function(){
response.redirect('/');
});
});
app.get('/restricted', restrict, function(request, response){
response.send('This is the restricted area! Hello ' + request.session.user + '! click <a href="/logout">here to logout</a>');
});
app.listen(8124, function(){
console.log('Server running...');
});
Now if you run the following command in the same directory as server.js…
node server
and then open up your browser to http://localhost:8124 you can see the homepage as defined by the default route.
Now try to go to http://localhost:8124/restricted. You can see that we are redirected to the login page. Judging from the code the username and password are “demo” and “demo”. If you login with these credentials, these get sent to the POST route for “/login” in a real application you’d store these credentials in a database, use a along with a per-user salt and you’d use some sort of encryption when you stored passwords. MongoDB is a popular option for using a database, and the bcrypt library is a good option for encryption. Node.js has it’s own crypto library that you could also make use of. The crypto library supports common hashing algorithms such as md5 and sha1. If you are extra-concerned with security bcrypt is recommended because it’s slower (i.e. takes longer to crack) compared to other hashing algorithims.
So in the end, you’d really end up having a login route like look something like the one below which uses a password hash encrypted with bcrypt and stored in a MongoDB database. Assuming that when the user was created his or her password was stored in the database using bcrypt…
var bcrypt = require(bcrypt);
...
app.post('/login', function(request, response) {
var username = request.body.username;
var password = request.body.password;
var salt = bcrypt.genSaltSync(10);
var hash = bcrypt.hashSync(password, salt);
var userObj = db.users.findOne({ username: username, password: hash });
if(userObj){
request.session.regenerate(function(){
request.session.user = userObj.username;
response.redirect('/restricted');
});
}
else {
res.redirect('login');
}
});
And you may end up wanting to separate some of the authentication code out into different methods as well. Refer to the libraries above for more info on how to install and use them.
Non Session-Based Authentication
One of the great things about Express is that it contains all of the tools that you need to create a REST API right out of the box. We’ve seen the GET and POST routes used. Express.js also supports PUT and DELETE routes as well. So all that you need to define the endpoints of your REST API comes standard with your Express installation.
When you speak of creating REST APIs though, one of the main concerns of adhering to truly RESTful principles is that the server is not supposed to maintain any record of state (i.e. no sessions). Thus, we have to turn to other possible solutions for authentication (and also authorization) when it comes to security. Three common ones include Basic Authentication, OAuth, and HMAC. There are some good discussions on how to implement these various methods of authentication in other sections. These are not specific to Node.js or Express, but many of the implementations there could easily be ported over to a REST API written using Express. They follow many of the similar patterns. For example a ‘products’ endpoint in PHP (Slim Framework)…
$app->get('/products', function () use ($app) {
...
});
and a products endpoint (Express)…
app.get('/products', function(request, response) {
...
});
are very similar and you could see how you could translate one to another.
Take a look at some of the entries below for discussions on different methods of authentication for a REST API…






0 Responses to Express.js Authentication