17

Node.js + Express + Passport を使用して簡易認証 (ローカル) を作成しています

これまでのところ、間違ったユーザー名またはパスワードを入力すると、ユーザーがエラーページにリダイレクトされるようになりました

しかし、ユーザーが正しいユーザー名とパスワードを入力すると、このエラーが発生します

node_modules\mongoose\lib\utils.js:435
    throw err;
          ^
TypeError: Object { _id: 50b347decfd61ab9e9e6768f,
username: 'saleh',
password: '123456' } has no method 'validPassword'

何が悪いのかわからない

app.js (不要なコードを削除しました):

  var passport = require('passport')
  , LocalStrategy = require('passport-local').Strategy;

  app.configure(function(){
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'ejs');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(passport.initialize());
  app.use(passport.session());
  app.use(app.router);
  app.use(express.static(path.join(__dirname, 'public')));
});



var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'authTest');

var authSchema = mongoose.Schema({ 
  username: 'string',
  password: 'string'
});

var User = db.model('users', authSchema);


passport.use(new LocalStrategy(
  function(username, password, done) {
    User.findOne({ username: username }, function (err, user) {
      if (err) { return done(err); }
      if (!user) {
        return done(null, false, { message: 'Incorrect username.' });
      }
      if (!user.validPassword(password)) {
        return done(null, false, { message: 'Incorrect password.' });
      }
      return done(null, user);
    });
  }
));



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

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




app.post('/login',
  passport.authenticate('local', { successRedirect: '/',
                                   failureRedirect: '/login/error',

                                  })
);

そして今、routes/login.jsにあります

var mongoose = require('mongoose');
var db = mongoose.createConnection('localhost', 'authTest');

var authSchema = mongoose.Schema({ 
    username: 'string',
    password: 'string'
});

var User = db.model('users', authSchema);

exports.index = function(req, res){
User.find(function (err, list) {
        res.render('login', { title: 'Usernames and Passwords', users: list,msg:""});
    });
};

御時間ありがとうございます。

4

3 に答える 3

17

使用している

if (!user.validPassword(password)) {
    return done(null, false, { message: 'Incorrect password.' });
}

しかし、メソッドを定義していませんvalidPassword。それをスキーマに添付します。

var authSchema = mongoose.Schema({ 
    username: 'string',
    password: 'string'
});
authSchema.methods.validPassword = function( pwd ) {
    // EXAMPLE CODE!
    return ( this.password === pwd );
};

EDITまた、スキーマを誤って定義しました。そのはず:

var authSchema = mongoose.Schema({ 
    username: String,
    password: String
});

私が何を意味するか知っているなら、両方usernameともstring ではなく型オブジェクトでpasswordなければならないことに注意してください。:)String"string"

于 2012-11-26T12:47:33.987 に答える
16

Jared が実装方法について言及していない、passportjs の Web サイトから例をコピーしたようです。

パスポート js github ページには、別の (より単純な) 例があります。彼は validPassword メソッドを完全に削除しました (18 行目):

if (user.password != password) { return cb(null, false); }

その上に、(暗号化を使用して) アプリを作成しました。

于 2012-11-26T12:54:35.680 に答える
5

これも初心者なので、これを理解するのに丸一日かかりました。Jared の別のサンプル アプリの履歴と、ここにいる人々からの暗号に関するアドバイスを使用しました。

最初に、ソルト (文字列化された大きな乱数) を生成し、ソルトとユーザーのパスワードを使用してハッシュを作成し (nodejs 'crypto' モジュールの助けを借りて)、最終的に両方のソルトを保存するメソッドを作成しました。そして、マングースが新しいアカウントを保存する前に毎回ハッシュします。

//make hash
userSchema.pre('save', function(next) {
    var user = this;
    if(!user.isModified('password')) return next();
    var rand = (Math.floor(Math.random() * 1000000000)).toString(36);
    var hash = crypto.createHash('md5').update(user.password + rand).digest("hex");
    user.password = hash;
    user.salt = rand;
    next();
});

検証のために、(ログイン時に) 入力したパスワードを取得し、salt を使用して同じハッシュを再度作成しようとしました。次に、保存されたハッシュと新しいハッシュを比較し、それに応じて true または false を返します。

 // Password verification
    userSchema.methods.validPassword = function(password) {
      var testhash = crypto.createHash('md5').update(password + this.salt).digest("hex");
      if(testhash === this.password) {
        return true;
      } else {
        return false;
      }
    }
于 2013-12-31T13:56:49.287 に答える