I was basically looking for the same thing. Specifically, I wanted the following:
- To use express.js, which wraps Connect's middleware capability
- "Form based" authentication
- Granular control over which routes are authenticated
- A database back-end for users/passwords
- Use sessions
What I ended up doing was creating my own middleware function check_auth
that I pass as an argument to each route I want authenticated. check_auth
merely checks the session and if the user is not logged in, then redirects them to the login page, like so:
function check_auth(req, res, next) {
// if the user isn't logged in, redirect them to a login page
if(!req.session.login) {
res.redirect("/login");
return; // the buck stops here... we do not call next(), because
// we don't want to proceed; instead we want to show a login page
}
// the user is logged in, so call next()
next();
}
Then for each route, I ensure this function is passed as middleware. For example:
app.get('/tasks', check_auth, function(req, res) {
// snip
});
Finally, we need to actually handle the login process. This is straightforward:
app.get('/login', function(req, res) {
res.render("login", {layout:false});
});
app.post('/login', function(req, res) {
// here, I'm using mongoose.js to search for the user in mongodb
var user_query = UserModel.findOne({email:req.body.email}, function(err, user){
if(err) {
res.render("login", {layout:false, locals:{ error:err } });
return;
}
if(!user || user.password != req.body.password) {
res.render("login",
{layout:false,
locals:{ error:"Invalid login!", email:req.body.email }
}
);
} else {
// successful login; store the session info
req.session.login = req.body.email;
res.redirect("/");
}
});
});
At any rate, this approach was mostly designed to be flexible and simple. I'm sure there are numerous ways to improve it. If you have any, I'd very much like your feedback.
EDIT: This is a simplified example. In a production system, you'd never want to store & compare passwords in plain text. As a commenter points out, there are libs that can help manage password security.
omniauth
(rails) or pythonsocial-auth
. PHP (and other common web server languages) users should feel free to add their equivalent as well. – forivall