我以前有过工作的Mongoose实例方法工作版本。我不确定这次有什么不同。这次我所做的唯一不同的事情是,我将server.js
文件之外的猫鼬连接功能分离为一个配置文件,该配置文件将被导入并调用connect()
函数。
我将主要在带本地策略的通行证中使用此实例方法来登录用户。当我在以前的UserModel.findOne({ email })
找到的用户实例上调用实例方法时,verify(password)
实例方法不会被调用,并且不会引发任何错误。
出于测试目的,我尝试将UserModel.findOne()
硬编码到连接字段中,但确实吸引了用户。然后,我决定立即从返回的名为verify()
的用户实例中调用实例方法。
我还试图将方法的名称更改为comparePassword
,我尝试使用静态测试来检查它是否被调用(不是),我也试图研究其他方式来导入我的模式和模型,但这似乎行不通。我已经尝试过Async / Await并没有改变输出
文件:mongo.db.js
const connect = () => {
return new Promise((resolve, reject) => {
mongoose.connect(
config.get('DB.STRING'),
{ useCreateIndex: true, useNewUrlParser: true },
async (err) => {
if (err) reject(err)
resolve()
// TESTING INSTANCE METHODS
await mongoose.connection
.collection('users')
// HARD CODED TEST EMAIL
.findOne({ email: 'braden_feeney@hotmail.com' }, (err, result) => {
if (err) reject(err)
console.log(result)
console.log(result.verify('test1234'))
})
},
)
})
}
const close = () => {
return mongoose.disconnect()
}
export default { connect, close }
文件:passport.config.js
passport.use(
new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
},
async (email, password, done) => {
try {
// Find the user given the email
const user = await User.findOne({ email })
// If not found
if (!user) return done(null, false)
// Check if the password is correct
const isValididated = await user.verify(password)
// If not matched
if (!isValididated) return done(null, false)
// Return the user
done(null, user)
} catch (error) {
done(error, false)
}
},
),
)
文件:users.model.js
const UserSchema = new Schema(
// HIDDEN FOR SECURITY
{ ... },
{ versionKey: false, timestamps: true },
)
// HIDDEN FOR SECURITY - PRE SAVE WORKS AS EXPECTED
UserSchema.pre('save', async function(next) { ... })
// THIS IS THE METHOD THAT SHOWS AS 'Not a Function'
UserSchema.methods.verify = function(password) {
bcrypt.compare(password, this.password, (err, res) => {
if (err) return new Error(err)
return res
})
}
export default model('User', UserSchema)
当我调用user.verify(password)
时,我希望看到布尔值要么从函数中返回。
实际结果是抛出错误,指出
TypeError: user.verify is not a function
答案 0 :(得分:0)
这部分没有意义:
async (email, password, done) => {
try {
const user = await User.findOne({ email })
if (user) // <-- if you have a user record
return done(null, false) // <-- you return!
// There was no valid user ... how would there be user.verify?
const isValididated = await user.verify(password)
if (!isValididated) return done(null, false)
done(null, user)
} catch (error) {
done(error, false)
}
}
您似乎返回了有效的用户,但是在没有用户时调用user.verify
。因此,看来您的流程有些问题。
答案 1 :(得分:0)
仔细研究过猫鼬如何创建实例方法后,我尝试使用另一种方法使该方法起作用。我不得不将bcrypt.compare()
包装在一个Promise中,因为我的代码没有等待响应。
文件:users.model.js
UserSchema.method('verify', function(password) {
return new Promise((resolve, reject) => {
bcrypt.compare(password, this.password, (err, res) => {
if (err) reject(err)
resolve(res)
})
})
})
我仍然更喜欢我的问题中提到的方式,因为我认为它看起来更干净,并且不依赖于字符串作为方法名称。