'use strict' /** * Module dependencies. */ var express = require('../..'); var hash = require('pbkdf2-password')() var path = require('node:path'); var session = require('express-session'); var app = module.exports = express(); // config app.set('view engine', 'ejs'); app.set('views', path.join(__dirname, 'views')); // middleware app.use(express.urlencoded()) app.use(session({ resave: false, // don't save session if unmodified saveUninitialized: false, // don't create session until something stored secret: 'shhhh, very secret' })); // Session-persisted message middleware app.use(function(req, res, next){ var err = req.session.error; var msg = req.session.success; delete req.session.error; delete req.session.success; res.locals.message = ''; if (err) res.locals.message = '
' + err + '
'; if (msg) res.locals.message = '' + msg + '
'; next(); }); // dummy database var users = { tj: { name: 'tj' } }; // when you create a user, generate a salt // and hash the password ('foobar' is the pass here) hash({ password: 'foobar' }, function (err, pass, salt, hash) { if (err) throw err; // store the salt & hash in the "db" users.tj.salt = salt; users.tj.hash = hash; }); // Authenticate using our plain-object database of doom! function authenticate(name, pass, fn) { if (!module.parent) console.log('authenticating %s:%s', name, pass); var user = users[name]; // query the db for the given username if (!user) return fn(null, null) // apply the same algorithm to the POSTed password, applying // the hash against the pass / salt, if there is a match we // found the user hash({ password: pass, salt: user.salt }, function (err, pass, salt, hash) { if (err) return fn(err); if (hash === user.hash) return fn(null, user) fn(null, null) }); } function restrict(req, res, next) { if (req.session.user) { next(); } else { req.session.error = 'Access denied!'; res.redirect('/login'); } } app.get('/', function(req, res){ res.redirect('/login'); }); app.get('/restricted', restrict, function(req, res){ res.send('Wahoo! restricted area, click to logout'); }); app.get('/logout', function(req, res){ // destroy the user's session to log them out // will be re-created next request req.session.destroy(function(){ res.redirect('/'); }); }); app.get('/login', function(req, res){ res.render('login'); }); app.post('/login', function (req, res, next) { if (!req.body) return res.sendStatus(400) authenticate(req.body.username, req.body.password, function(err, user){ if (err) return next(err) if (user) { // Regenerate session when signing in // to prevent fixation req.session.regenerate(function(){ // Store the user's primary key // in the session store to be retrieved, // or in this case the entire user object req.session.user = user; req.session.success = 'Authenticated as ' + user.name + ' click to logout. ' + ' You may now access /restricted.'; res.redirect(req.get('Referrer') || '/'); }); } else { req.session.error = 'Authentication failed, please check your ' + ' username and password.' + ' (use "tj" and "foobar")'; res.redirect('/login'); } }); }); /* istanbul ignore next */ if (!module.parent) { app.listen(3000); console.log('Express started on port 3000'); }