restricting access to all routes but one-Collection of common programming errors
I’m starting to experiment with expressJS + angularJS and i’ve run into a stressful situation.
My goal is to have one login page and one dashboard page, and using passport + mongodb i’ll authenticate a user in and, if credentials are correct, redirect him to the dashboard page.
I’ve started with the angular-express-seed and modified it so i ended up with the previously mentioned views:
$routeProvider.
when('/login', {
templateUrl: 'partials/login',
controller: 'LoginCtrl'
}).
when('/dashboard', {
templateUrl: 'partials/dashboard',
controller: 'DashboardCtrl'
}).
otherwise({
redirectTo: '/login'
});
I’m serving each partial view with:
app.get('/partials/:name', routes.partials);
exports.partials = function (req, res) {
var name = req.params.name;
res.render('partials/' + name);
};
The login system is working correctly except for the part that i can access the dashboard directly ( without loggin in at all ).
So i guess i need to figure out if the user if authenticated, before granting him access to the dashboard ( or any other area for that matter ).
I found this that does the trick:
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login');
}
and i would call it on every GET to a partial
app.get('/partials/:name', ensureAuthenticated, routes.partials);
the big problem here is that the login view is also a partial, and i dont want ensureAuthenticated to run when thats the view being requested.
Currently calling ensureAuthenticated on every partial request crashes any browser, no errors whatsoever.
What i’ve tried so far ( and did not work ):
function ensureAuthenticated(req, res, next) {
if ( req.route.params.name !== 'login' && req.isAuthenticated() ) { return next(); }
res.redirect('/login');
}
also tried calling the login view with its own app.GET and not using ensureAuthenticated but somehow angular flips off and does not even load.
Any ideas on how to resolve this ?
Thanks in advance.
-
It’s unclear to me if the first (unmodified) version of
ensureAuthenticated
crashes your browsers, or the last version (in which you check for/partials/login
), although no matter what, it shouldn’t happen (if by ‘crashing’ you mean ‘stalls’, that’s a tell-tale sign of Express not sending back a response)But as an alternative, try this:
app.get('/partials/login', routes.partials); app.get('/partials/:name', ensureAuthenticated, routes.partials);
Your
routes.partials
does have to check explicitly if it’s called for the login route, because in that case thename
parameter won’t exist inreq.params
.Just to make sure: do you have a server-side handler for
/login
as well? Otherwise theres.redirect('/login')
isn’t going to work. -
I don’t think that server side redirecting on XHR request is a good practice. XHR request should return 401 if the user is not authorized and the client side (Angular) should take the action as displaying notification message and redirecting user to the login partial. Look at this project for handling such requests. There are demo and blog post.