我正在按照一个教程尝试passport本地身份验证。一切看起来都很好,但是当我用Postman发出请求时,我得到这个错误:
[nodemon] 1.18.11
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `node server.js`
body-parser deprecated bodyParser: use individual json/urlencoded middlewares server.js:17:10
(node:6336) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
Started listening on PORT: 8080
events.js:167
throw er; // Unhandled 'error' event
^
TypeError: Cannot read property 'password' of undefined
at model.userSchema.methods.validPassword.password [as validPassword] (F:\Web Projects\LocalAuth\userModel.js:20:50)
at F:\Web Projects\LocalAuth\passport.js:34:21
at F:\Web Projects\LT1Kqob5UDEML61gCyjnAcfMXgkdP3wGcgGdBcFel.js:4672:16
at F:\Web Projects\LT1Kqob5UDEML61gCyjnAcfMXgkdP3wGcgGdBcFry.js:4184:12
at process.nextTick (F:\Web Projects\LT1Kqob5UDEML61gCyjnAcfMXgkdP3wGcgGdBcFry.js:2741:28)
at process._tickCallback (internal/process/next_tick.js:61:11)
Emitted 'error' event at:
at F:\Web Projects\LT1Kqob5UDEML61gCyjnAcfMXgkdP3wGcgGdBcFel.js:4674:13
at F:\Web Projects\LT1Kqob5UDEML61gCyjnAcfMXgkdP3wGcgGdBcFry.js:4184:12
at process.nextTick (F:\Web Projects\LT1Kqob5UDEML61gCyjnAcfMXgkdP3wGcgGdBcFry.js:2741:28)
at process._tickCallback (internal/process/next_tick.js:61:11)
[nodemon] app crashed - waiting for file changes before starting...
下面是我的用户模式:
const mongoose = require('mongoose');
const bcrypt = require('bcrypt-nodejs');
const Config = require ('./config');
mongoose.connect (Config.dbUrl);
let userSchema = new mongoose.Schema({
local : {
email: String,
password: String,
},
});
userSchema.methods.generateHash = password => {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.validPassword = password => {
return bcrypt.compareSync(password, this.local.password);
};
module.exports = mongoose.model('User', userSchema);
这是我的server.js文件:
const express = require ('express');
const session = require ('express-session');
const mongoose = require ('mongoose');
const bodyParser = require ('body-parser');
const cookieParser = require ('cookie-parser');
const morgan = require ('morgan');
const flash = require ('connect-flash');
const passport = require ('passport');
const PassHandler = require('./passport');
const app = express ();
const port = process.env.PORT || 8080;
app.use (morgan ('dev'));
app.use (bodyParser ({extended: false}));
app.use (cookieParser ());
app.use (
session ({secret: 'borkar.amol', saveUninitialized: true, resave: true})
);
//Initialize Passport.js
app.use (passport.initialize ());
app.use (passport.session ());
app.use (flash ());
//Global Vars for flash messages
app.use((req, res, next) => {
res.locals.successMessage = req.flash('successMessage');
res.locals.errorMessage = req.flash('errorMessage');
res.locals.error = req.flash('error');
next();
});
PassHandler(passport);
//Middleware to check if the user is logged in.
const isLoggedIn = (req, res, next) => {
if(req.isAuthenticated()) {
return next();
}
res.status(400).json({ message: 'You are not authenticated to acces this route.' });
}
app.get('/', (req, res) => {
res.json({ message: 'Local Auth API v0.1.0'});
});
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/user',
failureRedirect: '/signup',
failureFlash: true,
}));
app.post('/login', passport.authenticate('local-login', {
successRedirect: '/user',
failureRedirect: '/',
failureFlash: true,
}));
app.get('/user', isLoggedIn, (req, res) => {
res.json({ user: req.user, message: "User is logged in."});
});
app.listen (port, () => {
console.log (`Started listening on PORT: ${port}`);
});
下面是我使用的Passport策略:
passport.use (
'local-login',
new LocalStrategy (
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true,
},
function (req, email, password, done) {
User.findOne ({'local.email': email}, function (err, user) {
if (err) return done (err);
if (!user)
return done (
null,
{message: 'User not found.'},
req.flash ('errorMessage', 'No user found.')
);
if (!user.validPassword (password))
return done (
null,
{message: 'Invalid email or password.'},
req.flash ('errorMessage', 'Oops! Wrong password.')
);
// all is well, return successful user
return done (null, user);
});
}
)
);
老实说,我不知道出了什么问题。请帮帮忙。
**更新:**注册路径和注册策略运行正常。只有/login
路径有问题。
4条答案
按热度按时间ccrfmcuu1#
我也遇到了同样的问题。我通过将validatePassword方法从用户模式移到passport策略来解决我的问题。看起来密码没有被传递到UserSchema中的validatePassword方法。
"这是我的护照策略"
c2e8gylq2#
我重写了大部分的脚本,现在它可以工作了!下面是代码。
wgeznvg73#
将其定义为函数
之前
之后
我不知道为什么它不能与箭头回调一起工作
fquxozlt4#
“在传统函数表达式中,“this”关键字根据调用它的上下文绑定到不同的值。但是,对于箭头函数,这是按词汇绑定的。这意味着它使用包含箭头函数的代码中的“this”。”-引用自freeCodeCamp
在这里,我们使用userSchema中的“this”,而不是arrow函数本身中的“this”。因此,您应该将arrow函数更改为经典函数表达式。