Animus
Animus

Reputation: 843

Which package is more preferable to use in a real project mongodb or mongoose?

First of all, this answer is not what I'm looking for.

I'm adding a DB to the educational project. For the previous one, I've just queried the DB with MongoDB.MongoClient and got/set the records with MongoDB.MongoClient.collection.insertOne.

For example, adding user is as simple as:

mongodb.MongoClient.collection("users").insertOne({
    username, 
    password // jsut a sha512 password, which is sent hashed from UI
})

But as far as I understood, the right way(a better way) is to create a Mongoose Schema and add function to it. But the password creation seems way trickier than expected. Why is that a difference? If a password is stolen from UI, it doesn't matter how many encryptions used. However, if the password is simply hashed, it doesn't matter if you steal it from back-end - it's impossible to trigger that endpoint with an already hashed password.

const UserSchema = new mongoose.Schema({
    username: {
        type: String,
        lowercase: true,
        unique: true,
        index: true,
        required: [true, 'username can\'t be blank'],
        match: [/^[a-zA-Z0-9]+$/, 'username is invalid'],
    },
    salt: String,
    hash: String,
});

UserSchema.plugin(uniqueValidator, {message: 'is already taken.'});

UserSchema.methods.setPassword = function(password) {
    this.salt = crypto.randomBytes(16).toString('hex');
    this.hash = crypto.pbkdf2Sync(password, this.salt, 10000, 512, 'sha512').toString('hex');
};

Basically, the question is: Which way is better and is any of the ways imply, that I have to use that huge encryption? As far as I understand, it's possible to have 1 single file with mongodb.collection(*) functions, or dozens of schemas. Why the answer is still not obvious?

Upvotes: 0

Views: 129

Answers (1)

Ivan Cherviakov
Ivan Cherviakov

Reputation: 538

  1. Mongoose using mongodb driver under the hood
  2. It is not good practice to put cpu/memory heavy tasks on client side
  3. Nor mongoose not mongodb native driver forcing you to use anything, wether to hash password or not (and how heavy encryption should be used) is totally up to you.

So basically I would recommend you to make use of native mongo driver, use just any pretty simple hashing from nodejs docs and just add hashing on user creation before you make insert:

const hash = (password) => {
  const hash = crypto.createHash('sha256');
  hash.update(password);
  return hash.digest('hex');
}

...

app.post('/user', async (req, res) => {
  try {
    // validation of user credentials here
    const userToInsert = { ...req.body, password: hash(req.body.password) };
    await mongodb.MongoClient.collection("users").insertOne(userToInsert);
    res.status(201).send("done");
  } catch (err) {
    console.error(err);
    res.status(500).send('internal server error');
  }
})

Upvotes: 1

Related Questions