简体   繁体   中英

how doe export work in javaScript wold. hash undefined bcryptjs

Let's say we have two file, user.js users.js in user.js we have. Why can we do module.exports.. we can use in it diff .js file? what does "@returns Promise If callback has been omitted" means it is from the bcrypt.genSalt function? I also have a github repo, so please take a look if you have a bit of time. after cloning it

stuck in terminal

    result { error: null,
  value:
   { email: 'max@mail.com',
     username: 'max',
     password: '1234',
     confirmationPassword: '1234' },
  then: [Function: then],
  catch: [Function: catch] }
hash undefined


const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const bcrypt = require('bcryptjs');


const userSchema = new Schema({
  email: String,
  username: String,
  password: String
});


const User = mongoose.model('user', userSchema);
module.exports = User;
module.exports.hashPassword = (password) => {
 return hash = bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash(password, salt, function(err, hash) {
    });
});
}; 

in users.js we have have

const express = require('express');
const router = express.Router();
const Joi = require('joi');
const User = require('../models/user');   



const userSchema = Joi.object().keys({
  email:Joi.string().email().required(),
  username:Joi.string().required(),
  password:Joi.string().regex(/^[a-zA-Z0-9]{3,15}$/).required(),
  confirmationPassword:Joi.any().valid(Joi.ref('password')).required()
});



router.route('/register')
  .get((req, res) => {
    res.render('register');
  })
  .post(async (req, res, next) => {
    try{
        const result =  Joi.validate(req.body,userSchema);
        console.log('result',result);

        if(result.error) {
          req.flash('error', 'Data is not valid, please try again');
          res.redirect('/users/register');
          return;
        //console.log('result',result);
      }
      //  checking if email is already taken
      const user =  await User.findOne({'email':result.value.email });
        if (user){
          req.flash('error','Email is already in use');
          res.redirect('/users/register');
          return;
        }


     // console.log('hash',hash);

      // Hash the password
      const hash = await User.hashPassword(result.value.password); 
      console.log('hash',hash);

  } catch(error) {
    next(error);
    }
  });
module.exports = router;

based the example given by bcrypt

var bcrypt = require('bcryptjs');
bcrypt.genSalt(10, function(err, salt) {
    bcrypt.hash("B4c0/\/", salt, function(err, hash) {
        // Store hash in your password DB.
    });
});

adding pic for mongo db 在此处输入图片说明

I think the problem lies in this line:

const hash = await User.hashPassword(result.value.password);

This implies that User.hashPassword(result.value.password) should be returning a promise (but it returns a reference to the wrong promise).

module.exports.hashPassword = (password) => {
    return hash = bcrypt.genSalt(10, function (err, salt) {
        bcrypt.hash(password, salt, function (err, hash) {});
    });
};

Perhaps modifying the above to return a promise may help.. Like so:

module.exports.hashPassword = (password) => {
    var salt = await bcrypt.genSalt(10);
    return bcrypt.hash(password, salt);
};

To answer your question about @returns Promise If callback has been omitted :

Bcrypt methods are asynchronous. Which means they return immediately and process in the background. When the result is available, the function makes this available to the calling code either via a callback function or a promise.

Consider the following API for genSalt from the docs:

genSalt(rounds, minor, cb)

rounds - [OPTIONAL] - the cost of processing the data. (default - 10)

minor - [OPTIONAL] - minor version of bcrypt to use. (default - b)

cb - [OPTIONAL] - a callback to be fired once the salt has been generated. uses eio making it asynchronous. If cb is not specified, a Promise is returned if Promise support is available.

  err - First parameter to the callback detailing any errors. salt - Second parameter to the callback providing the generated salt. 

What that says is genSalt can take three arguments: genSalt(rounds, minor, cb)

Sample using callbacks

If the calling code wants the result via a callback, it can pass a function which looks like function(err, salt){} as the cb parameter.

 bcrypt.genSalt(rounds, minor, function(err, salt){
     if(err){
         //Handle error
         return;
     }
     // Salt is available here
     console.log(salt);
 });

Sample using promises

If the cb parameter is not passed (null or undefined) the function returns a Promise instead.

 var promise = bcrypt.genSalt(rounds, minor);
 promise
     .then(function(salt){
         // Salt is available here
         console.log(salt);
     })
     .catch(function(err){
         // Handle error
     });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM