How to do it...

Let's follow these steps to add a User model to our application with secure password handling:

  1. First, we will replace our /models/authors.js model configuration with a slightly enhanced /models/users.js model configuration:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var userSchema = new Schema({
firstName: String,
lastName: String,
email: { type: String, unique: true, required: true },
password: { type: String, required: true },
role: String,
});

module.exports = mongoose.model('user', userSchema);
  1. Next, we will include bcrypt and configure a pre-save method to perform a password hashing function on our password before writing it to the database. We will also implement a custom function for comparing a provided password with this hash to check whether it's a match, without ever requiring us to save the actual password to our database:
var bcrypt = require('bcrypt');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var userSchema = new Schema({
firstName: String,
lastName: String,
email: { type: String, unique: true, required: true },
password: { type: String, required: true },
role: String,
});

userSchema.pre('save', function(next) {
var user = this;
if (!user.isModified('password')) return next();

bcrypt.genSalt(function(error, salt) {

if (error) return next(err);

bcrypt.hash(user.password, salt, function(error, hash) {

if (error) return next(err);

user.password = hash;
next();
});
});
});

userSchema.methods.comparePassword = function(testPassword, callback) {

bcrypt.compare(testPassword, this.password, function(error, isMatch) {
if (error) return callback(error);
callback(null, isMatch);
});
};

module.exports = mongoose.model('user', userSchema);
  1. We will need to upgrade our /routes/api/login.js route configuration to use our new User model to validate that the username and password are still a match:
...
var Users = require('../../models/users');

...
var login = function(req, res, next) {
var username = req.body.username;
var password = req.body.password;

if (username && password) {
Users.findOne({ email: username }, function(error, user) {
if (error || !user) return res.status(401).json(authError('Invalid username or password for user authentication.'));

user.comparePassword(password, function(error, match) {

if (error) return res.status(401).json(authError('Invalid username or password for user authentication.'));
if (match) {

req.session.user = user;
next();
} else {

res.status(401).json(authError('Invalid username or password for user authentication.'));
}

});
})
;
} else {
res.status(401).json(authError('Must provide username or password for user authentication.'));
}
};

...
  1. Finally, we can update our /database.js mocks to use our new User model. We will also manually create an admin user that is guaranteed to have the same username and password:
...
var User = require('./models/users');
...
mongoose.connect('mongodb://localhost/mean-db').then(function() {
if (env == 'development') {
var faker = require('faker');

generateMock(Post, 30, function() {
var markdown = faker.lorem.sentences();
markdown += "## " + faker.lorem.sentence() + " ";
markdown += "[" + faker.lorem.words() + "](" + faker.internet.url() + ") ";

return {
title: faker.lorem.words(),
content: markdown,
published: faker.date.past(),
author: new User({
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
email: faker.internet.email(),
password: faker.internet.password(),
role: 'author'
})

}
});

User.deleteMany({}, function() {
var admin = new User({
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
email: '[email protected]',
password: 'Secret',
role: 'admin'
});

admin.save().then(function(user) {

console.log("created new admin: " + user.email);
});
})
;
}
}, function(error) {
console.error('failed to connect to MongoDB...', error);
});

module.exports = mongoose.connection;
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.38.24