【问题标题】:TypeError: done is not a function and TypeError: assert not a functionTypeError: done is not a function and TypeError: assert not a function
【发布时间】:2017-03-23 11:54:43
【问题描述】:

我正在做一个平均堆栈应用程序,现在我正在注册和登录身份验证。但我有两个错误! 如果我有“passReqToCallback:true”,它会给我“完成不是一个函数”,但是当我评论它时它很好。但我不需要吗?

之后它告诉我 assert 不是一个函数,然后我尝试用 check 切换它,它告诉我 check 不是一个函数。 我很困惑为什么它会给出这些错误

var passport = require('passport');
var  User = require('../models/User');
var LocalStrategy = require('passport-local').Strategy;
var validator = require('express-validator');


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('local.register', new LocalStrategy({
usernameField: 'username',
emailField: 'email',
passwordField: 'password',
passReqToCallback : true
}, function(req, username, email, password, done){
req.assert('username', 'Invalid username').notEmpty();
req.assert('email', 'Invalid email').notEmpty().isEmail();
req.assert('password', 'Invalid password').notEmpty().isLength({min: 4});

var errors = req.validationErrors();


if(errors){
var messages = [];
errors.forEach(function(error){
messages.push(error.msg);
});
return done(null, false, req.flash('error', messages));
}
User.findOne({'username':username}, function(err, user){
if(err){
return done(err);
}
if(user){
return done(null, false, {message:'Username is already use'});
}

var newUser = new User();
newUser.username = username;
newUser.email = email;
newUser.password = newUser.encryptPassword(password);
newUser.save(function(err, result) {
if (err) {
return done(err);
}
return done(null , newUser);
});
});
}));
passport.use('local.sign-in', new LocalStrategy({
usernameField: 'username',
passwordField: 'password',
passReqToCallback: true
}, function(req, username, password, done){
req.assert('username', 'Invalid username').notEmpty();
req.assert('password', 'Invalid password').notEmpty();
var errors = req.validationErrors();
if(errors){
var messages = [];
errors.forEach(function(error){
messages.push(error.msg);
});
return done(null, false, req.flash('error', messages));
}
//find user
User.findOne({'username': username}, function(err, user){
if(err){
return done(err);
}

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

     }));

【问题讨论】:

标签: mongodb authentication express passport.js


【解决方案1】:

根据https://github.com/jaredhanson/passport-local#available-options,唯一的选项是usernameFieldpasswordField,如果passReqToCallbackfalse,回调只接受username, password, done作为参数,如果是req, username, password, done,则回调只接受req, username, password, done。回调中的email 参数不应该存在。

为了能够使用req.assert,您需要有权访问request 对象,因此,您需要传递passReqToCallback: true

应该是这样的:

passport.use('local.register', new LocalStrategy({
    usernameField: 'username',
    passwordField: 'password',
    passReqToCallback : true
}, function(req, username, password, done) {
    req.assert ...
});

这应该可以解决您的两个问题。

【讨论】:

  • 好的,它确实修复了它,但对于我的应用程序,它使用用户名电子邮件和密码。那我是怎么收到邮件的?或者唯一的选择是那些
  • 这些是唯一的选项,如果您想使用email 字段而不是username,请将usernameField 值更改为'email'usernameField: 'email'
  • 糟糕的无法使用电子邮件并创建用户名。但是非常感谢你:)
  • 没问题:)。一个疑问:为什么要检查用户名、电子邮件和密码?用户名/密码或电子邮件/密码应该不够,因为用户名和电子邮件应该是唯一的?
  • 那是真的:P哈哈我可能想多了:P