使用Node-bcrypt和Passport.JS检索Salted PW

时间:2013-07-11 18:57:29

标签: bcrypt passport.js

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

我使用nodejs,express,mongodb,mongoose,passport js,bcrypt。

我想做什么

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

我做了什么 我知道我的路由,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('/');
    }
  });
});

1 个答案:

答案 0 :(得分:0)

我会这样做:

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

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:请为一个用户使用'user'

对于模型,请使用“用户”