Redirection to Requested URL After Login in NodeJS

July 14, 2014    node nodejs javascript js passport authentication login security

While working on an app built on NodeJS, I was faced with a problem where users would be redirected to the homepage after successful login even though they had requested a different URL, contained in the mail they would receive.

The solution was obvious but trivial given the size of the app itself. Changing routes for the login process was not a solution since almost the ful lapp was depenedent on these routes.

After a disappointing search on Google, I racked my brains for a few hours before I finally had a working solution and it got the job done perfectly without changing any siginificant part of the app.

We are using the Passport library for Node to implement oAuth login. Passport lets you define your own custom oAuth login process which is what we are doing.

This what a typical route looks like in the app that requires authentication to view:

app.get('/api/comments', auth.requiresLogin, comment.list);  

The ‘auth.requiresLogin’ is what checks if the user is logged in. If not, the user is redirected to the login page.

exports.requiresLogin = function (req, res, next) {
    if (!req.isAuthenticated() || !req.isAuthenticated) {  
        if (req.session) {  
            req.session.redirectUrl = req.headers.referer || req.originalUrl || req.url;  
        }  
        next('Not logged in');  
    } else {
        next();  
    }  
};  

The first line is self-explanatory. The second line

if (!req.isAuthenticated() || !req.isAuthenticated)  

is a built in request parameter by passport which checks if the user is authenticated. Next, if the session exists in the request parameter, we assigned a new property to the session object. It can be any name you want but to keep it straight forward and easy to understand, we give it the name redirectUrl.

We assign the referer URL, or the original requested URL to the newly defined object property. This is the URL that the user requested and we keep it in memory to redirect the user to, after login.

Finally, the route for a successful login might look like this:

app.get('/auth/callback', auth.callback, auth.successLoginRedirect);  
var callback = passport.authenticate('myapp', { failureRedirect: '/error' });  

var successLoginRedirect = function (req, res) {
  User.findById(req.user._id);

  var redirectionUrl = req.session.redirectUrl || '/home';
  res.redirect(redirectionUrl);
};  

And there you have it. The successLoginRedirect function looks up the user based on their ID and finally we use the stored URL in the session object. If the user did not request a URL, we redirect them to the homepage.



comments powered by Disqus