Skip to content

Instantly share code, notes, and snippets.

@veer66
Last active May 31, 2016 09:29
Show Gist options
  • Save veer66/6056119 to your computer and use it in GitHub Desktop.
Save veer66/6056119 to your computer and use it in GitHub Desktop.
Incomplete user authentication code using pbkdf2, node.js and Q
var express = require('express');
var app = express();
var nconf = require('nconf');
var Q = require("q");
var crypto = require('crypto');
app.use(express.bodyParser());
app.post("/user/auth", function(req, res) {
res.set('Content-Type', 'application/json');
authUser(req.body.username, req.body.password).then(function(auth_result) {
if(auth_result) {
res.status(200);
res.send(JSON.stringify({status: "success"}));
} else {
res.status(401);
res.send(JSON.stringify({status: "fail"}));
}
});
});
app.post("/user/create", function(req, res) {
createUser('admin', 'abcd').then(function() {
res.set('Content-Type', 'application/json');
res.send(JSON.stringify({status: "created"}));
}).done();
});
function createSalt() {
var deferred = Q.defer();
crypto.randomBytes(32, function(err, buf) {
if(err) {
deferred.reject(new Error(err));
}
var salt = buf.toString('hex');
deferred.resolve(salt);
});
return deferred.promise;
}
function createPasswordHash(password, salt) {
var deferred = Q.defer();
// Adapted from http://stackoverflow.com/questions/11557467/node-js-crypto-pbkdf2-password-to-hex
crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
if(err) {
deferred.reject(new Error(err));
}
var hash = Buffer(encodedPassword, 'binary').toString('hex');
deferred.resolve(hash);
});
return deferred.promise;
}
function findUserByUsername(username) {
var deferred = Q.defer();
user_col.find({username: username})
.success(function(user_list) {
if(user_list.length == 1) {
deferred.resolve(user_list[0]);
} else {
deferred.resolve(null);
}
})
.error(function(err) {
deferred.reject(new Error(err));
});
return deferred.promise;
}
function createUser(username, password) {
var salt_;
var user_;
return findUserByUsername("admin").then(function(user) {
user_ = user;
return createSalt();
}).then(function(salt) {
salt_ = salt;
return createPasswordHash("abcd", salt);
}).then(function(hash) {
if(user_ == null) {
user_col.insert({username: "admin", password_hash: hash, salt: salt_});
} else {
user_col.update({username: "admin"},
{'$set': {password_hash: hash, salt: salt_}});
}
});
}
function createPasswordHash(password, salt) {
var deferred = Q.defer();
// Follow this code http://stackoverflow.com/questions/11557467/node-js-crypto-pbkdf2-password-to-hex
crypto.pbkdf2(password, salt, 25000, 512, function(err, encodedPassword) {
if(err) {
deferred.reject(new Error(err));
}
var hash = Buffer(encodedPassword, 'binary').toString('hex');
deferred.resolve(hash);
});
return deferred.promise;
}
function authUser_(user, password) {
var deferred = Q.defer();
if(user != null) {
createPasswordHash(password, user.salt).then(function(hash) {
deferred.resolve(hash === user.password_hash);
});
} else {
deferred.resolve(false);
}
return deferred.promise;
}
function authUser(username, password) {
return findUserByUsername(username).then(function(user) {
return user;
}).then(function(user) {
return authUser_(user, password);
});
}
app.listen(nconf.get('port'));
console.log('Listening on port ' + nconf.get('port'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment