Node.js 和 Passport 对象没有方法 validPassword
Posted
技术标签:
【中文标题】Node.js 和 Passport 对象没有方法 validPassword【英文标题】:Node.js and Passport Object has no method validPassword 【发布时间】:2012-11-13 22:36:49 【问题描述】:我正在使用 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:"");
);
;
感谢您的宝贵时间。
【问题讨论】:
【参考方案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"
,如果你明白我的意思的话。 :)
【讨论】:
如果可以的话,还有一个问题.. 你能推荐一本书或任何资源来更好地学习 Node.js 吗? @MuhammadSaleh 我不知道任何 Node.JS 书籍。我通过不断的谷歌搜索学到了一切。从Node.JS main page 上的教程开始。然后只是谷歌。 *** 也是一个很好的知识来源。我就是这样学会的。 不过,这是用于 Passport 的。不应该已经有了哈希密码和检查密码的功能吗?【参考方案2】:看起来你从 passportjs 网站复制了示例,Jared 没有提及如何实现它。
在护照 js github 页面上,他有另一个(更简单的)示例;他完全删除了 validPassword 方法(第 18 行):
Example
if (user.password != password) return cb(null, false);
这就是我基于它的应用程序(使用加密)的基础。
【讨论】:
谢谢我真的需要一个更简单的例子,我还联系了 Jared 以制作更好的文档:)【参考方案3】:我也是一个菜鸟,我花了一整天的时间才弄清楚这个。我使用了 Jared 的另一个示例应用程序的历史记录,以及来自这里的人们的一些加密建议。
首先我做了一个方法来生成一个盐(一个大的随机数,被字符串化),使用盐和用户的密码来创建一个哈希(在 nodejs 'crypto' 模块的帮助下),最后存储每次 mongoose 保存新帐户之前的 salt 和 hash。
//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;
【讨论】:
当你意识到这是一岁的那一刻。 没关系 :) 感谢贡献 这个答案可能应该更新,因为使用 md5 和Math.random
不安全。以上是关于Node.js 和 Passport 对象没有方法 validPassword的主要内容,如果未能解决你的问题,请参考以下文章
为移动应用程序进行 facebook 登录的正确方法是啥(使用 node.js/passport.js 服务器)
使用 passport.js 和 express.js (node.js) 制作安全的 oauth API
测试受保护的 api 调用、mocha、supertest、node js、passport