Mongodb TypeError:[函数]不是Passport本地策略中的函数
我正在尝试使用Passport.js在本地对用户进行身份验证,同时不保留会话并使用我自己的JWToken 我遵循本教程: 同时阅读Passport.js文档。我不知道出了什么问题,但passport似乎没有注意到某些函数确实是函数 我有一个加载函数,可以根据特定条件(用户可以使用电子邮件或电话号码登录)从DB(mongo)中选择一个用户 我正在呼叫passport.authenticate在我的路线中:Mongodb TypeError:[函数]不是Passport本地策略中的函数,mongodb,express,passport.js,Mongodb,Express,Passport.js,我正在尝试使用Passport.js在本地对用户进行身份验证,同时不保留会话并使用我自己的JWToken 我遵循本教程: 同时阅读Passport.js文档。我不知道出了什么问题,但passport似乎没有注意到某些函数确实是函数 我有一个加载函数,可以根据特定条件(用户可以使用电子邮件或电话号码登录)从DB(mongo)中选择一个用户 我正在呼叫passport.authenticate在我的路线中: // Controllers // const Users = require('../.
// Controllers //
const Users = require('../../app/controllers/users');
...
...
app.post('/api/login', passport.authenticate('local', { failureRedirect: '/api/login' }), Users.login);
以下是我的本地策略:
const mongoose = require('mongoose');
const User = mongoose.model('User');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy;
passport.use(new LocalStrategy(
{
usernameField: 'email',
phoneField: 'phone',
passwordField: 'password',
session: false
},
function(email, phone, password) {//cb == callback
const options = {
criteria: { email: email, phone: phone },
select: 'name username email hashed_password salt'
};
User.load(options, function(err, user) {
if (err || !user){
return res.status(400).json({
type: 'failure',
message: "User creation failed",
data: [err]
});
};
if (!user.authenticate(password)) {
return res.status(400).json({
type: 'failure',
message: "User creation failed",
data: [err]
});
};
req.login(user, {session: false}, (err) => {
if (err) {
res.send(err);
}
// generate a signed son web token with the contents of user object and return it in the response
const token = jwt.sign(user.id, 'your_jwt_secret');
return res.json({user, token});
});
});
}
));
我得到以下错误:
TypeError: res.status is not a function
在试图从passport和Response取回东西之前。我试图用cb(callback)来做这件事,就像在教程中做的那样,但是我一直得到相同的错误
提前感谢您的帮助 您在如何实施Passport的本地策略方面存在一些问题,这些问题会造成问题 当Passport的本地startegy只接受一个字段时,您尝试使用两个字段作为用户名。(见:)
如果您想将两者都用作用户名,您可能需要考虑创建自己的自定义策略。这将更加深入,但您可以从Passport Github页面()开始学习
第二个问题是,您正试图让Passport在本地策略中发送响应,而这并不是它想要做的。相反,您应该将错误和返回值传递给Passport的done()
函数,该函数将相应地处理它们
以下是您的本地策略的示例:
passport.use(
new LocalStrategy(async (email, phone, password, done) => {
const options = {
criteria: { email, phone },
select: 'name username email hashed_password salt',
};
try {
const user = await User.load(options);
/**
* If null is returned meaning there was no user found, send the done call
* with the false flag. This tells passport to redirect to the failure URL.
*/
if (!user) {
return done(null, false);
}
/**
* If the user's password is incorrect, also return the done function with the false
* flag. This tells passport to redirect to the failure URL.
*/
if (!user.authenticate(password)) {
return done(null, false);
}
/**
* If a user is found and their password is verified, send the user object to
* the done function. This will tell Passport to call the next middelware attaching
* the user object.
*/
return done(null, user);
} catch (err) {
/**
* If there is an error with the DB call, return generic message
* for security purposes.
*/
return done('There was an internal server error.');
}
})
);
load: options => {
return new Promise(async (resolve, reject) => {
options.select = options.select || 'email phone';
try {
const user = await this.findOne(options.criteria)
.select(options.select)
.exec();
resolve(user);
} catch (err) {
reject(err);
}
});
};
还有一个加载函数的示例:
passport.use(
new LocalStrategy(async (email, phone, password, done) => {
const options = {
criteria: { email, phone },
select: 'name username email hashed_password salt',
};
try {
const user = await User.load(options);
/**
* If null is returned meaning there was no user found, send the done call
* with the false flag. This tells passport to redirect to the failure URL.
*/
if (!user) {
return done(null, false);
}
/**
* If the user's password is incorrect, also return the done function with the false
* flag. This tells passport to redirect to the failure URL.
*/
if (!user.authenticate(password)) {
return done(null, false);
}
/**
* If a user is found and their password is verified, send the user object to
* the done function. This will tell Passport to call the next middelware attaching
* the user object.
*/
return done(null, user);
} catch (err) {
/**
* If there is an error with the DB call, return generic message
* for security purposes.
*/
return done('There was an internal server error.');
}
})
);
load: options => {
return new Promise(async (resolve, reject) => {
options.select = options.select || 'email phone';
try {
const user = await this.findOne(options.criteria)
.select(options.select)
.exec();
resolve(user);
} catch (err) {
reject(err);
}
});
};
作为一般的最佳实践,我将您的回调更改为更新的promises()方法
这应该按照您打算使用Passport的方式进行