I need a little help figuring out how to get this working -- I've tested and have working JWT authentication and SSL on my '/user' routes. I'm trying to safely allow the user to upload an audio file, also using the JWT and SSL route.
The authentication middleware works, and multer works to let me upload files when I comment out the authentication middleware. However, when I leave the middleware in, the uploaded file is created on my system, but the file fails to upload properly and I get a 404 error.
Thanks for any help!
server.js (main file)
var express = require('express')
, app = express()
, passport = require('passport')
, uploads = require('./config/uploads').uploads
, user_routes = require('./routes/user')
, basic_routes = require('./routes/basic')
, jwt = require('jwt-simple');
// get our request parameters
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Use the passport package in our application
app.use(passport.initialize());
require('./config/passport')(passport);
//double check we have an ssl connection
function ensureSec(req, res, next) {
if (req.headers['x-forwarded-proto'] == 'https') {
return next();
} else {
console.log('NOT SSL PROTECTED! rejected connection.');
res.redirect('https://' + req.headers.host + req.path);
}
}
app.use(ensureSec);
//authenticate all user routes with passport middleware, decode JWT to see
//which user it is and pass it to following routes as req.user
app.use('/user', passport.authenticate('jwt', {session:false}), user_routes.middleware);
//store info on site usage- log with ID if userRoute
app.use('/', basic_routes.engagementMiddleware);
// bundle our user routes
var userRoutes = express.Router();
app.use('/user', userRoutes);
userRoutes.post('/upload', uploads:q, function(req,res){
res.status(204).end("File uploaded.");
});
// Start the server
app.listen(port);
routes/basic_routes.js (tracks engagement middleware)
var db = require('../config/database')
, jwt = require('jwt-simple')
, getIP = require('ipware')().get_ip
, secret = require('../config/secret').secret;
exports.engagementMiddleware = function(req, res, next){
if (typeof(req.user) == 'undefined') req.user = {};
var postData = {};
var ip = getIP(req).clientIp;
var fullUrl = req.protocol + '://' + req.get('host') + req.originalUrl;
if (req.method=="POST") postData = req.body;
var newEngagement = new db.engagementModel({
user_id: req.user._id,
ipAddress: ip,
url: fullUrl,
action: req.method,
postData: postData
});
//log the engagement
newEngagement.save(function(err) {
if (err) {
console.log('ERROR: engagement middleware db write failed');
next();
}
console.log('LOG: user ' + req.user._id +' from ipAddress: ' + ip + ': ' + req.method + ' ' + fullUrl);
next();
});
next();
}
config/passport.js (passport authentication middleware)
var JwtStrategy = require('passport-jwt').Strategy;
// load up the user model
var db = require('../config/database'); // get db config file
var secret = require('../config/secret').secret;
module.exports = function(passport) {
var opts = {};
opts.secretOrKey = secret;
passport.use(new JwtStrategy(opts, function(jwt_payload, done) {
db.userModel.findOne({id: jwt_payload.id}, function(err, user) {
if (err) {
return done(err, false);
}
if (user) {
done(null, user);
} else {
done(null, false);
}
});
}));
};
routes/user_routes.js (user route middleware, user add to header)
var jwt = require('jwt-simple');
var db = require('../config/database');
var secret = require('../config/secret').secret;
//expose decoded userModel entry to further routes at req.user
exports.middleware = function(req, res, next){
var token = getToken(req.headers);
if (token) req.user = jwt.decode(token, secret);
else res.json({success: false, msg: 'unable to decode token'});
//should be unnecessary, double checking- after token verification against db
db.userModel.findOne({email: req.user.email}, function (err, user) {
if( err || !user ) {
console.log('something has gone horribly wrong. Token good, no user in db or access to db.');
return res.status(403).send({success: false, msg: 'unable to find user in db'});
}
});
//end unnecessary bit
next();
}
//helper function
getToken = function (headers) {
if (headers && headers.authorization) {
var parted = headers.authorization.split(' ');
if (parted.length === 2) return parted[1];
else return null;
} else { return null; }
};
config/uploads.js (finally where we try to upload)
var moment = require('moment');
var multer = require('multer');
var jwt = require('jwt-simple');
var uploadFile = multer({dest: "audioUploads/"}).any();
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'audioUploads/')
},
filename: function (req, file, cb) {
cb(null, req.user._id + '_' + moment().format('MMDDYY[_]HHmm') + '.wav')
}
});
exports.uploads = multer({storage:storage}).any();
in your server.js do this:
const authWare = passport.authenticate('jwt', {session:false});
userRoutes.post('/upload', authWare, uploads:q, function(req,res){
res.status(204).end("File uploaded.");
});
works for me!
Related
many hours spent on reading books, passport.org and similar issues in stackoverflow. However, still had no clue why login failed using passport to authenticate with simple local strategy of username and password. passport.autheticate came back stating with info="missing credential" and user='false".
before stepping into passport.authenticate, confirmed that req.body had the right user info of username and password from Angular.
Besides, user registration using passport worked, however, using same username and password was not able to log in.
Below pls find code and thanks for any help in advance.
App.js (code associated with user registration and login)
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var logger = require('morgan');
var session = require('express-session');
var FileStore = require('session-file-store')(session);
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var authenticate = require('./lib-general/authenticate');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var User = require('./model/user');
var app = express();
const util = require('util');
var debug = require('debug')('http'),
http = require('http'),
name ='pIn3-server';
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cookieParser());
app.use( bodyParser.urlencoded({ extended: true }) );
app.use(session({
name: 'session-id',
secret: config.secretKey,
saveUninitialized: false,
resave: false,
store: new FileStore()
}));
app.use(passport.initialize());
app.use(passport.session());
app.use('/', indexRouter);
app.use('/', usersRouter);
authenticate.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('../model/user');
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('../config.js');
passport.use(new LocalStrategy(User.authenticate(),{passReqToCallback : true}));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
console.log("before getToken");
exports.getToken = function(user) {
return jwt.sign(user, config.secretKey,
{expiresIn: 3600});
};
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
console.log("after jwtFromRequest - extract JWT");
console.log(opts.jwtFromRequest);
opts.secretOrKey = config.secretKey;
console.log("after secretOrKey");
console.log(opts.secretOrKey);
exports.jwtPassport = passport.use(new JwtStrategy(opts,
(jwt_payload, done) => {
console.log("JWT payload: ", jwt_payload);
User.findOne({_id: jwt_payload._id}, (err, user) => {
if (err) {
return done(err, false);
}
else if (user) {
return done(null, user);
}
else {
return done(null, false);
}
});
}));
exports.verifyUser = passport.authenticate('jwt', {session: false});
Users.js (user router)
var express = require('express');
const bodyParser = require('body-parser');
var User = require('../model/user');
var passport = require('passport');
var authenticateMy = require('../lib-general/authenticate'); // use my to distinguish from passport authenticate
var LocalStrategy = require('passport-local').Strategy;
var cors = require('./cors');
var userRouter = express.Router();
userRouter.use(bodyParser.json());
const mongoose = require('mongoose');
const mongooseClient = require('mongoose'); /* this is important */
console.log("step into router users");
/*ensure if it from right port of whitelist in cors:3000, 3443, 4200 */
userRouter.options('*', cors.corsWithOptions, (req, res) => { res.sendStatus(200); } )
/* Get users listing. */
userRouter.get('/',cors.cors,function(req,res,next){
res.send('respond with a resource')
});
userRouter.post('/signup', cors.corsWithOptions,(req, res, next) => {
console.log('2.0.0.1 - at register',req.body);
let newUser = new User( {
_id: new mongoose.Types.ObjectId(),
username: req.body.username,
password: req.body.password,
firstName: req.body.firstName,
lastName: req.body.lastName,
role: req.body.role,
remember: req.body.remember }); // from book
User.register(newUser, req.body.password, (err, user) => {
if(err) {
console.log('2.0.0.2 - at register',err,user);
res.statusCode = 500;
res.setHeader('Content-Type', 'application/json');
res.json({err: err});
}
else {
console.log('2.0.1 - at register',req.body);
user.save((err, user) => {
if (err) {
res.statusCode = 500;
res.setHeader('Content-Type', 'application/json');
res.json({err: err});
return ;
}
passport.authenticate('local')(req, res, () => {
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json({success: true, status: 'Registration Successful!'});
});
});
}
});
});
userRouter.post('/login', cors.corsWithOptions, (req, res, next) => {
console.log('2.0.4 - at login',req.body);
passport.authenticate('local', (err, user , info) => {
console.log('2.0.5 - at login', user, info);
if (err)
return next(err);
if (!user) {
res.statusCode = 401;
res.setHeader('Content-Type', 'application/json');
res.json({success: false, status: 'Login Unsuccessful!', err: info});
}
req.logIn(user, (err) => {
if (err) {
console.log('2.0.6 - at req.login',user);
res.statusCode = 401;
res.setHeader('Content-Type', 'application/json');
res.json({success: false, status: 'Login Unsuccessful!', err: 'Could not log in user!'});
}
var token = authenticateMy.getToken({_id: req.user._id});
res.statusCode = 200;
res.setHeader('Content-Type', 'application/json');
res.json({success: true, status: 'Login Successful!', token: token});
});
}) (req, res, next);
});
userRouter.get('/logout', (req, res) => {
console.log('in userRouter logout code')
if (req.session) {
req.session.destroy();
res.clearCookie('session-id');
res.redirect('/');
}
else {
console.log('in userRouter log out ')
var err = new Error('You are not logged in!');
err.status = 403;
next(err);
}
});
I'm a little back end developer for the node js. Currently, I'm creating an application to increase my skill level with node js. So I thought i'd try to learn JSON webtoken(jwt) for the user authentication part. I am using this link to get an idea of how it works. But now I have a problem that I must change and then fix that differs from the tutorial. The middleware that the tutorial gives you is not working for the secured routes. So let me describe what happens when my code runs. If we didn't provide any token to any route that the middleware checks then the router works as we expect it to without returning any errors from the middleware. So please let me know a solution to fix this in the easiest possible way. Thank you.
secured routes file for api
//Node js libraries
const express = require('express');
const router = express.Router();
const app = express();
const jwt = require('jsonwebtoken');
//Static files
const Users = require('../models/users');
app.set('superSecret', 'thisissecretkeyforapi');
//Routes here
router.post('/', function(req, res){
if(req.body.username == '' || req.body.password == '') {
res.send('Fields must be required');
}
else {
Users
.findOne({
username: req.body.username
},
function(err, user){
if(!user){
res.send('No user found');
}
else {
if(user.password != req.body.password) {
res.send('Wrong password');
}
else {
var token = jwt.sign(user, app.get('superSecret'), {
expiresIn: 60*15
});
res.send({
message: "Token here",
token: token
})
}
}
});
}
})
router.get('/profile', function(req, res){
console.log(req.decoded);
res.send('profile here');
});
module.exports = router;
app.js file for all middlewares
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://cordy:lolla123#ds042459.mlab.com:42459/musiclk', {
useMongoClient: true
});
app.set("view engine", "ejs");
app.set('superSecret', 'thisissecretkeyforapi');
app.use(morgan('dev'));
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(bodyParser.json());
require('./controllers/index')(app);
app.set('superSecret', 'thisissecretkeyforapi');
admin_routes = require('./controllers/admin_routes');
admin_routes.use(function(req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, app.get('superSecret'), function(err, decoded) {
if (err) {
return res.json({
success: false,
message: 'Failed to authenticate token. The token is expired' });
}
else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no to
// return an error
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
app.use('/admin', admin_routes);
app.listen(process.env.PORT || 1337, function(){
console.log("Now listening for the requests");
});
There is all of my code.
I have some problems with the express session where I cannot retrieve my session variable that I had stored previously. Below are parts of my codes that I had written.
server.js
let express = require('express'),
path = require('path'),
bodyParser = require('body-parser'),
cors = require('cors'),
config = require('./config/database'),
expressSession = require('express-session'),
uid = require('uid-safe'),
db;
let app = express();
//Import Routes
let auth = require('./routes/auth'),
chimerListing = require('./routes/chimer-listing'),
brandListing = require('./routes/brand-listing');
//Specifies the port number
let port = process.env.PORT || 3000;
// let port = 3000;
// Express session
app.use(expressSession({
secret: "asdasd",
resave: true,
saveUninitialized: false,
cookie: {
maxAge: 36000000,
secure: false
}
}));
//CORS Middleware
app.use(cors());
//Set Static Folder
var distDir = __dirname + "/dist/";
app.use(express.static(distDir));
//Body Parser Middleware
app.use(bodyParser.json());
//MongoDB
let MongoClient = require('mongodb').MongoClient;
MongoClient.connect(config.database, (err, database) => {
if (err) return console.log(err)
db = database;
//Start the server only the connection to database is successful
app.listen(port, () => {
console.log('Server started on port' + port);
});
});
//Make db accessbile to routers;
app.use(function(req, res, next) {
req.db = db;
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.set('Access-Control-Allow-Headers', 'Content-Type');
next();
});
//Routes
app.use('/login', auth);
app.use('/user-listing', userListing);
app.use('/brand-listing', brandListing);
//Index Route
app.get('/', (req, res) => {
res.send('Invalid Endpoint');
});
genuuid = function() {
return uid.sync(18);
};
auth.js
let express = require('express'),
router = express.Router(),
db;
//Login Router for chimer
router.post('/chimer', (req, res, next) => {
db = req.db;
// let client = req.client;
db.collection('chimeUser').find({
Username: req.body.username,
Password: req.body.password
}).toArray().then(function(docs) {
//If there is such user
if (docs.length >= 1) {
req.session.chimerId = docs[0]._id;
console.log(req.session);
req.session.save(function(err) {
// session saved
if (err)
console.log(err)
res.json({
success: true,
chimerId: docs[0]._id
//objects: docs
});
})
} else {
res.json({
success: false,
//objects: docs
})
}
});
});
//Login Router brand
router.post('/brand', (req, res, next) => {
db = req.db;
db.collection('brand').find({
Username: req.body.username,
Password: req.body.password
}).toArray().then(function(docs) {
req.session.brand = docs;
console.log(req.session.brand);
//If there is such user
if (docs.length >= 1) {
res.json({
success: true,
//objects: docs
})
} else {
res.json({
success: false,
//objects: docs
})
}
//db.close()
});
});
});
module.exports = router;
user-listing.js
let express = require('express'),
moment = require('moment'),
router = express.Router(),
// ObjectID = require('mongodb').ObjectID,
db, client;
// let applyListing = require('../models/chimer-listing');
//Retrieve All Listing
router.get('/getAllListing', (req, res, next) => {
db = req.db;
console.log(req.session)
db.collection('listing').find().toArray().then(function(listing) {
//If there is any listing
if (listing.length >= 1) {
res.json({
success: true,
results: listing
})
} else {
res.json({
success: false,
})
}
//db.close()
});
});
module.exports = router;
So in my server.js, I have three routes file which is auth, user-listing, and brand-listing.
Firstly, a user will need to login with the web application which is developed in angular2 and this will trigger the auth route. It will then check for the credentials whether does it exist in the database if it exists I will then assign an ID to req.session.chimerId so that in other routes I will be able to use this chimerId.
Next, after the user has logged in, they will then retrieve an item listing. The problem arises where I can't seem to retrieve the req.session.chimerId that I had previously saved. It will be undefined
NOTE: I tried this using Postman and the browser. In the Postman it works, I am able to retrieve back the req.session.chimerId whereas when I use the angular2 application to hit the endpoints req.session.chimerId is always null
I'm having trouble with my server routes, I had the server on heroku but now have it local to debug,
On browser inspection i get
404 (Not Found)
in browser window
Cannot GET /api/auth/register
My server.js
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var logger = require('morgan');
var bodyParser = require('body-parser');
var databaseConfig = require('./config/database');
var router = require('./app/routes');
//CORS middleware
var allowCrossDomain = function(req, res, next) {
if ('OPTIONS' == req.method) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,PATCH,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With');
res.sendStatus(200);
}
else {
next();
}
};
app.use(allowCrossDomain);
mongoose.connect(databaseConfig.url);
app.listen(process.env.PORT || 8080);
console.log("App listening on port 8080");
app.use(bodyParser.urlencoded({ extended: false })); // Parses urlencoded bodies
app.use(bodyParser.json()); // Send JSON responses
app.use(logger('dev')); // Log requests to API using morgan
router(app);
My routes.js
var AuthenticationController = require('./controllers/authentication'),
ExerciseController = require('./controllers/exercises'),
express = require('express'),
passportService = require('../config/passport'),
passport = require('passport');
var requireAuth = passport.authenticate('jwt', {session: false}),
requireLogin = passport.authenticate('local', {session: false});
module.exports = function(app){
var apiRoutes = express.Router(),
authRoutes = express.Router(),
exerciseRoutes = express.Router();
// Auth Routes
apiRoutes.use('/auth', authRoutes);
//authRoutes.post('/register', AuthenticationController.register);
authRoutes.post('/register', function(req, res){
AuthenticationController.registerUser
});
authRoutes.post('/login', requireLogin, AuthenticationController.login);
authRoutes.get('/protected', requireAuth, function(req, res){
res.sendStatus({ content: 'Success'});
});
// Exercise Routes
apiRoutes.use('/exercises', exerciseRoutes);
exerciseRoutes.get('/', requireAuth, AuthenticationController.roleAuthorization(['client','trainer','admin']), ExerciseController.getExercises);
exerciseRoutes.post('/', requireAuth, AuthenticationController.roleAuthorization(['trainer','admin']), ExerciseController.createExercise);
exerciseRoutes.delete('/:exercise_id', requireAuth, AuthenticationController.roleAuthorization(['trainer','admin']), ExerciseController.deleteExercise);
// Set up routes
app.use('/api', apiRoutes);
}
And my Controller Authentication.js :
var jwt = require('jsonwebtoken');
var User = require('../models/user');
var authConfig = require('../../config/auth');
function generateToken(user){
return jwt.sign(user, authConfig.secret, {
expiresIn: 10080
});
}
function setUserInfo(request){
return {
_id: request._id,
email: request.email,
role: request.role,
trainer: request.trainer,
programs: request.programs
};
}
exports.login = function(req, res, next){
var userInfo = setUserInfo(req.user);
console.log(userInfo)
res.status(200).json({
token: 'JWT ' + generateToken(userInfo),
user: userInfo
});
}
exports.registerUser = function(req, res, next){
var email = req.body.email;
var password = req.body.password;
var role = req.body.role;
var trainer = req.body.trainer;
var programs= req.body.programs;
if(!email){
return res.status(422).send({error: 'You must enter an email address'});
}
if(!password){
return res.status(422).send({error: 'You must enter a password'});
}
User.findOne({email: email}, function(err, existingUser){
if(err){
return next(err);
}
if(existingUser){
return res.status(422).send({error: 'That email address is already in use'});
}
var user = new User({
email: email,
password: password,
role: role,
trainer: trainer,
programs: programs
});
user.save(function(err, user){
if(err){
return next(err);
}
var userInfo = setUserInfo(user);
res.status(201).json({
token: 'JWT ' + generateToken(userInfo),
user: userInfo
})
});
});
}
exports.roleAuthorization = function(roles){
return function(req, res, next){
var user = req.user;
User.findById(user._id, function(err, foundUser){
if(err){
res.status(422).json({error: 'No user found.'});
return next(err);
}
if(roles.indexOf(foundUser.role) > -1){
return next();
}
res.status(401).json({error: 'You are not authorized to view this content'});
return next('Unauthorized');
});
}
}
I dont have much experience with express/node so im not sure where im going wrong, could be something simple im just not able to see, anyways any help is greatly appreciated , not sure if you need more info, this is going to be the back end for an ionic 2 app
I am trying to create a sign up where the user if already existing in the db is logged into the system, or else a new user is created in the system.
So far I have come up with the following code.
//filename passport-config
var config = require('./config');
var passport = require('passport');
var User = require('./models/user');
var LocalStrategy = require('passport-local').Strategy;
var isValidPassword = function(user, password){
return bCrypt.compareSync(password, user.password);
};
// Generates hash using bCrypt
var createHash = function(password){
return bCrypt.hashSync(password, bCrypt.genSaltSync(10), null);
}
// As with any middleware it is quintessential to call next()
// if the user is authenticated
var isAuthenticated = function (req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
passport.use('signup', new LocalStrategy({
passReqToCallback : true
},
function(req, email, password, done) {
findOrCreateUser = function(){
// find a user in Mongo with provided email
User.findOne({'email':email},function(err, user) {
// In case of any error return
if (err){
console.log('Error in SignUp: '+err);
return done(err);
}
// already exists
if (user) {
User.findOne({ 'email' : email },
function(err, user) {
if (!user){
console.log('User Not Found with email '+email);
return done(null, false);
}
// User exists but wrong password, log the error
if (!isValidPassword(user, password)){
console.log('Invalid Password');
return done(null,false);
}
});
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.email = email;
newUser.password = createHash(password);
// save the user
newUser.save(function(err) {
if (err){
console.log('Error in Saving user: '+err);
throw err;
}
console.log('User Registration succesful');
return done(null, newUser);
});
}
});
};
// Delay the execution of findOrCreateUser and execute
// the method in the next tick of the event loop
process.nextTick(findOrCreateUser);
})
);
my router
router.post('/signup', passport.authenticate('signup', {
successRedirect: '/timeslot',
failureRedirect: '/'
}));
my server.js file
var express = require('express');
var bodyParser = require('body-parser');
var leisure = require('leisure');
var cors = require('cors');
var passport = require('passport');
var config = require('./config');
var passportConfig = require('./passport-config');
var session = require('express-session')
var expressHbs = require('express-handlebars');
var mediaTypes = [
{ contentType: 'application/hal+json' },
{ contentType: 'application/json' },
{ contentType: 'text/html' }
];
var app = express();
/*Handlebars */
app.engine('handlebars', expressHbs({layout: false}) );
app.set('view engine', 'handlebars');
app.use(express.static(__dirname + '/assets'));
app.use(cors(config.settings.cors));
app.use(bodyParser());
app.use(leisure.accept(mediaTypes));
/*sessions */
app.use(session({
secret: 'keyboardSFS23432##!#!#at'
}));
app.use(passport.initialize());
app.use(passport.session());
var routes = require('./routes');
app.use('/', routes.router);
function start () {
var port = process.env.PORT || 3000;
app.listen(port);
console.log('Appoints service started on port ' + port);
}
exports.app = app;
exports.start = start;
The signup route doesn't work at all and I am pretty confused on how to debug this, any suggestions will be appreciated.
Have a look at the excellent article at
http://scotch.io/tutorials/javascript/easy-node-authentication-setup-and-local
and the sample code at
https://github.com/scotch-io/easy-node-authentication (with MongoDB), or
https://github.com/tobilg/easy-node-authentication-redis (with Redis as backend)