【问题标题】:Retrieve Salted PW using Node-bcrypt and Passport.JS使用 Node-bcrypt 和 Passport.JS 检索盐渍密码
【发布时间】:2013-07-10 04:33:23
【问题描述】:

我有一个问题,我可以在 node-bcrypt 和 passport.js 中创建散列密码,但无法使用散列密码。

我正在使用 nodejs、express、mongodb、mongoose、passport js、bcrypt。

我想做什么

能够正常登录,但使用 bcrypt salted 密码等。

我做了什么 我知道我的路由、api 和 db 都在工作。由于我当前的设置会登录和注销用户,如果我使用普通字符串作为密码而不是 bcrypt。

我还检查了我的数据库,密码字段中出现了 bcrypt/salted 密码。

我从这篇文章中得到了使用 bcrypt 的想法(所以使用这段代码): http://devsmash.com/blog/password-authentication-with-mongoose-and-bcrypt

这是我的相关代码:

var express = require('express'),
    routes = require('./routes'),
    passport = require('passport'),
    util = require('util'),
    flash = require('connect-flash'),
    LocalStrategy = require('passport-local').Strategy,
    mongoose = require('mongoose');

mongoose.connect('mongodb://54.254.96.11/bcrypt')
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId;

 bcrypt = require('bcrypt'),
    SALT_WORK_FACTOR = 10;

var user = new Schema({
username: { type: String, required: true, index: { unique: true } },
    password: { type: String, required: true },
  email: String
  });

var user = mongoose.model('user', user);

//Bcrypt Code

user.pre('save', function(next) {
    var guest = this;

    // only hash the password if it has been modified (or is new)
    if (!guest.isModified('password')) return next();

    // generate a salt
    bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
        if (err) return next(err);

        // hash the password using our new salt
        bcrypt.hash(guest.password, salt, function(err, hash) {
            if (err) return next(err);

            // override the cleartext password with the hashed one
            guest.password = hash;
            next();
        });
    });
});

user.methods.comparePassword = function(candidatePassword, cb) {
    bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
        if (err) return cb(err);
        cb(null, isMatch);
    });
};


//
passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  user.findById(id, function (err, user) {
    done(err, user);
  });
});

passport.use(new LocalStrategy(
  function(username, password, done) {
    // asynchronous verification, for effect...
    process.nextTick(function () {

      // Find the user by username.  If there is no user with the given
      // username, or the password is not correct, set the user to `false` to
      // indicate failure and set a flash message.  Otherwise, return the
      // authenticated `user`.
      user.findOne({ username: username}, function(err, user) {
        if (err) { return done(err); }
        if (!user) { return done(null, false, { message: 'Unknown user ' + username }); }
        if (user.password != password) { return done(null, false, { message: 'Invalid password' }); }
        return done(null, user);
      })
    });
  }
));


// Relevant Express Routes

app.post('/login',
  passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
  function(req, res) {
    res.redirect('/home');
  });


app.post('/create', function(req, res, next){
  var moot = new user({
    "username": req.body.username,
    "password" : req.body.password,
    "email" : req.body.email});


  moot.save(function (err) {
    if (!err) {
      res.redirect('/home');
    }
    else {
      res.redirect('/');
    }
  });
});

【问题讨论】:

    标签: bcrypt passport.js


    【解决方案1】:

    我会这样做:

    为用户模型创建一个新方法:

    userSchema.statics.authenticate = function(username, password, callback)
    {
        this.findOne({username: username}, function(err, user)
        {
            if(err) return callback(err);
    
            if(!user) return callback(null, false);
    
    
            user.comparePassword(password, function(err, correct)
            {
                if(!correct) return callback(null, false);
    
                callback(null, user);
            });
    
        });
    }
    

    然后在护照配置中:

    passport.use(new LocalStrategy(
        function(username, password, done)
        {
            User.authenticate(username, password, function(err, user)
            {
               if(err) return done(err);
               if(!user) return done(null, false);
    
               done(null, user);
            }
        }
    ));
    

    这应该可以(我没有测试过)

    PS:请使用“用户”作为一个用户

    对于模型,使用“用户”

    【讨论】:

      最近更新 更多