Authenticating requests

The main part of our application is our user dashboard, where our user will be able to create giftlists. Previously, we would access a user's dashboard by passing the user id in the dashboard URL. Obviously, there is no authentication here, and it's not a secure way of doing it.

Now we want users to log in before viewing only their own dashboard. If they go to the dashboard URL directly, they should be redirected to a login page.

We are going to handle this in stereotypical Express fashion by writing a piece of middleware to handle adding authentication for routes.

Adding authentication-check middleware

Passport gives us in-session access to check if a user is currently authenticated. We can use this to easily protect whole sections of an application, or add authentication on a route-by-route basis.

Create a new file called authenticated.js in your utils directory:

var authenticated = function (req, res, next) { 
 
    if (req.isAuthenticated()){ 
        return next(); 
    } else { 
        res.redirect('/login'); 
    } 
 
} 
 
module.exports = authenticated; 

Our authenticated function is set up with the signature of all Express middleware—with arguments for request, response, and next. We check the return value of a call to the request object's isAuthenticed() function—this is something Passport provides to us.

If we are authenticated, we merely pass the request forward by calling next(). If we aren't authenticated, we will redirect the request to the /login route, rendering our login page.

Inserting middleware into routes

Next, we want to insert our new middleware where we want to use it, in our dashboard route file:

var express = require('express'); 
var router = express.Router(); 
var isAuthenticated = require('../utils/authenticated');
router.get('/', isAuthenticated, function(req, res, next) {
    res.send('respond with a resource');
}); 
 
router.param('id', function(req, res, next, id) { 
    var db = req.db; 
    var collection = db.get('giftlist'); 
 
    collection.find({'owner_id':id}, {}, function(err,giftlists){ 
        if(err){ 
            res.send(err); 
        }else if(giftlists){ 
            req.giftlists = giftlists; 
            collection = db.get('users'); 
            collection.findOne({"_id":id}, function(err, user){ 
                if(err){ 
                    res.send(err); 
                } else { 
 
                    req.user = user; 
                    next(); 
                } 
 
            }); 
 
        } else { 
            res.send(new Error('User not found.')); 
        } 
    }); 
}); 
 
 
 
router.get('/:id', function(req, res, next){ 
    res.render('dash/dashboard', {user: req.user, giftlists: req.giftlists}); 
}); 
 
module.exports = router; 

We require our new module into the router file, assigning it to the isAuthenticated variable. Next, we add the middleware to the main route.

Restarting your server should log you out. If you want to log out without restarting your server, you can access the sign-out route at http://localhost:3000/login/signout. You can then try to access /dash, and you'll be redirected back to login. Signing back in as a valid user will redirect you to dash, which will render properly.

Changing the dashboard route

Before, we set up our dash/:id route to look up the user using a param function. That's no longer going to suit our purposes. What we want is to show an authenticated user their own dashboard after logging in. Fortunately, Passport has already cached the user data we need in-session for us so we don't have to look the user up every time we render the dashboard.

Let's make some changes to our dashboard router:

var express = require('express'); 
var router = express.Router(); 
var isAuthenticated = require('../utils/authenticated'); 
 
router.get('/', isAuthenticated, function(req, res, next) { 
 
 
    var db = req.db; 
    var collection = db.get('giftlist'); 
 
    collection.find({'owner_id':req.user._id}, {}, function(err,giftlists){ 
        if(err){ 
            res.send(err); 
        }else { 
            giftlists = giftlists || []; 
            res.render('dash/dashboard', {user: req.user, giftlists: giftlists}); 
        } 
    }); 
}); 
 
module.exports = router; 

Now we've simplified the code a bit. Our /:id route is now gone and the only route remaining is the main route, which gets triggered by get requests to /dash.

We already have user data cached in the request thanks to Passport, so it saves us one database lookup, helping our code perform better. We still look up the gift lists owned by this user, then we render the dashboard template we built earlier, which contains our single-page application frontend.

We get the following:

Changing the dashboard route

So we have authenticated the user and stashed the user object in the session, making it available during the request.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.97.170