Skip to content

Instantly share code, notes, and snippets.

@fardjad
Last active April 29, 2020 00:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fardjad/f0c89ba73db1316dc475 to your computer and use it in GitHub Desktop.
Save fardjad/f0c89ba73db1316dc475 to your computer and use it in GitHub Desktop.
[Password Authentication with Mongoose] #nodejs #mongodb #authentication
{
"name": "mongoose-password-auth",
"version": "1.0.0",
"description": "My attempt to improve http://blog.mongodb.org/post/32866457221/password-authentication-with-mongoose-part-1",
"scripts": {
"test": "mocha -R spec"
},
"author": "Fardjad Davari <public@fardjad.com>",
"license": "MIT",
"devDependencies": {
"mocha": "^2.2.5",
"node-uuid": "^1.4.3"
},
"dependencies": {
"bcrypt": "^0.8.3",
"mongoose": "^4.0.6"
}
}
/**
* test/test-model.js
*/
'use strict';
var mocha = require('mocha');
var assert = require('assert');
var mongoose = require('mongoose');
var uuid = require('node-uuid');
var MONGODB_ADDRESS = 'localhost';
var TEST_DATABASE_NAME = 'test_password_auth_' + uuid.v4();
var CONNECTION_STRING = 'mongodb://' + MONGODB_ADDRESS + '/' + TEST_DATABASE_NAME;
// sample user to be saved on the db
var USERNAME = 'test';
var PASSWORD = 'password';
var User = require('../model/user');
var savedUser;
describe('User', function() {
before(function beforeCallback(done) {
mongoose.connect(CONNECTION_STRING);
var db = mongoose.connection;
db.on('error', function dbErrorCallback(err) {
assert.fail(err);
});
db.once('open', function() {
done();
});
});
after(function afterCallback(done) {
mongoose.connection.db.dropDatabase(function dropCallback(err) {
if (err) {
console.error(err);
}
mongoose.connection.close(done);
});
});
describe('#save', function() {
this.timeout(0);
it('should save the user', function(done) {
var user = new User({
username: USERNAME,
password: PASSWORD
});
user.save(function saveCallback(err, user) {
savedUser = user;
done();
});
});
});
describe('#compare', function() {
this.timeout(0);
it('should compare the just set password and the saved hash', function(done) {
savedUser.comparePassword(PASSWORD, function compareCallback(err, result) {
assert.ifError(err);
assert.ok(result);
done();
});
});
});
});
/**
* model/user.js
*/
'use strict';
var SALT_WORK_FACTOR = 10;
var mongoose = require('mongoose');
var bcrypt = require('bcrypt');
var Schema = mongoose.Schema;
var UserSchema = new Schema({
username: { type: String, required: true, index: { unique: true } },
password: { type: String, required: true }
});
// hash the password before save
UserSchema.pre('save', function preSaveCallback(next) {
// user
var _this = this;
// only hash the password if it has been modified (or is new)
if (!_this.isModified('password')) {
return next();
}
// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function genSaltCallback(err, salt) {
if (err) {
return next(err);
}
// hash the password along with our new salt
bcrypt.hash(_this.password, salt, function hashCallback(err, hash) {
if (err) {
return next(err);
}
// override the cleartext password with the hashed one
_this.password = hash;
next();
});
});
});
UserSchema.methods.comparePassword = function comparePassword(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function compareCallback(err, isMatch) {
if (err) {
return cb(err);
}
cb(null, isMatch);
});
};
module.exports = mongoose.model('User', UserSchema);
@EmmyMay
Copy link

EmmyMay commented Apr 29, 2020

tried this but the this.password is undefined

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment