Node.js и объект Passport не имеет метода validPassword
Обратите внимание, что я новичок в Node.js, поэтому, пожалуйста, будьте терпеливы со мной:)
Я использую Node.js + Express 3 + 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',
})
);
и теперь в маршрутах /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:""});
});
};
Спасибо за ваше время.
Ответы
Ответ 1
Ну, это очевидно, не так ли? Вы используете
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
и password
должны быть String
объекты типа, а не строки "string"
, если вы знаете, что я имею в виду.:)
Ответ 2
Похоже, вы скопировали пример с веб-сайта паспортного сайта, где Джаред не упомянул, как его реализовать.
На странице паспорта js github у него есть другой (более простой) пример; он вообще удалил метод validPassword (строка 18):
Example
if (user.password != password) { return cb(null, false); }
Это то, на чем я основал мое приложение (используя шифрование) поверх него.
Ответ 3
Кроме того, будучи нобом, мне потребовался целый день, чтобы понять это. Я использовал историю из другого примера приложений Jared и некоторых криптовых советов от людей здесь.
Сначала я создал метод, который генерирует соль (большое случайное число, которое является строгим), использует соль и пароль пользователя для создания хэша (с помощью модуля криптоопределения nodejs) и, наконец, сохраняет как соль, так и хэш каждый раз, прежде чем мангуст сохраняет новую учетную запись.
//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();
});
Для проверки я просто беру введенный пароль (при входе в систему) и пытаюсь снова сделать тот же хеш с помощью соли. Затем я сравниваю сохраненный хеш с новым и возвращает соответственно 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;
}
}