模型“用户”的路径“_id”中值“586cc8b3ea780c071bbe2469”的值“586cc8b3ea780c071bbe2469”转换为 ObjectId 失败
Posted
技术标签:
【中文标题】模型“用户”的路径“_id”中值“586cc8b3ea780c071bbe2469”的值“586cc8b3ea780c071bbe2469”转换为 ObjectId 失败【英文标题】:Cast to ObjectId failed for value "586cc8b3ea780c071bbe2469" at path "_id" for model "User" 【发布时间】:2017-05-18 14:39:34 【问题描述】:我看到了一些与我类似的帖子,但我仍然收到同样的错误
这是我的用户架构
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
var userSchema = mongoose.Schema(
local:
email: String,
password: String,
,
);
userSchema.methods.generateHash = function(password)
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
;
userSchema.methods.validPassword = function(password)
return bcrypt.compareSync(password, this.local.password);
;
module.exports = mongoose.model('User', userSchema);
我的路线
var express = require('express');
var passport = require('passport');
var router = express.Router();
router.get('/', function(req, res, next)
res.render('index', title: 'Express' );
);
router.get('/login', function(req, res, next)
res.render('login.ejs', message: req.flash('loginMessage') );
);
router.get('/signup', function(req, res)
res.render('signup.ejs', message: req.flash('loginMessage') );
);
router.get('/profile', isLoggedIn, function(req, res)
res.render('profile.ejs', user: req.user );
);
router.get('/logout', function(req, res)
req.logout();
res.redirect('/');
);
router.post('/signup', passport.authenticate('local-signup',
successRedirect: '/profile',
failureRedirect: '/signup',
failureFlash: true,
));
router.post('/login', passport.authenticate('local-login',
successRedirect: '/profile',
failureRedirect: '/login',
failureFlash: true,
));
module.exports = router;
function isLoggedIn(req, res, next)
if (req.isAuthenticated())
return next();
res.redirect('/');
我的 app.js
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongoose = require('mongoose');
var flash = require('connect-flash');
var session = require('express-session');
var routes = require('./routes/index');
var users = require('./routes/users');
var configDB = require('./config/database.js');
mongoose.connect(configDB.url);
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded( extended: false ));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use(session( secret: 'shhsecret' ));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
require('./config/passport')(passport);
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next)
var err = new Error('Not Found');
err.status = 404;
next(err);
);
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development')
app.use(function(err, req, res, next)
res.status(err.status || 500);
res.render('error',
message: err.message,
error: err
);
);
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next)
res.status(err.status || 500);
res.render('error',
message: err.message,
error:
);
);
module.exports = app;
这是我的passport.js,我使用的是本地护照
var LocalStrategy = require('passport-local').Strategy;
var User = require('../models/user');
module.exports = function(passport)
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-signup', new LocalStrategy(
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true,
,
function(req, email, password, done)
process.nextTick(function()
User.findOne( 'local.email': email , function(err, user)
if (err)
return done(err);
if (user)
return done(null, false, req.flash('signupMessage', 'That email is already in use.'));
else
var newUser = new User();
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
newUser.save(function(err)
if (err)
throw err;
return done(null, newUser);
);
);
);
));
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, false, req.flash('loginMessage', 'No user found.'));
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Wrong password.'));
return done(null, user);
);
));
;
passport 可以将用户保存到数据库中
expressauth 5 > db.users.find()
"_id" : ObjectId("586cc8b3ea780c071bbe2469"), "local" : "password" : "$2a$08$vANw7GJIk8RUVEpJWnwSpOVQ77RuHCjbXiGoQVl.Fx/thhbMkEVWu", "email" : "david@david.com" , "__v" : 0
expressauth 6 >
对于模型“用户”的路径“_id”中的值“586cc8b3ea780c071bbe2469”,转换为 ObjectId 失败
我已经构建了几个使用护照 oauth 的应用程序,与上面显示的方式完全相同。所以我不知道为什么会出现这个错误。
有什么建议吗?
【问题讨论】:
【参考方案1】:mongoose
版本 > 4.7.2 也有同样的问题
问题是关于bson 包。
我通过安装旧版本的猫鼬解决了这个问题。
npm install mongoose@4.7.2
或者您可以更改 package.json 以使用确切的版本 4.7.2 "mongoose": "4.7.2"
问题解决后,您可以更新到较新的版本。您可以在here 上跟踪它。
【讨论】:
【参考方案2】:passport
中的 serializeUser
函数中存在错误。
您需要使用user._id
而不是user.id
。
因为在您的UserSchema
中没有field
作为id
,所以user.id
将是undefined
,而deserializing
是用户,undefined
不是typeOf
ObjectId
,因此它抛出了错误。
试试这个:
passport.serializeUser(function(user, done)
done(null, user._id);
);
更新:
在您的 deserializeUser
中执行此操作:
将即将到来的id
转换为ObjectId
,只是为了确定,然后将ID
转换为query
User
。
var userId = mongoose.Schema.Types.ObjectId(id);
User.findById(userId , function(err, user)
done(err, user);
);
不要忘记在同一个文件中包含mongoose
。
var mongoose=require('mongoose');
希望这会对你有所帮助。
【讨论】:
我更新了 user._id,但我仍然遇到同样的错误。但是在反序列化用户函数中出现了错误。 你能告诉我console.log(id)
在deserializeUser
中打印了什么吗?
在 deserializeUser 中打印出的 id 与我收到错误“586cc8b3ea780c071bbe2469”时显示的 id 相同。
你还在面对这个问题吗?
将猫鼬版本更改为 4.7.2 对我有用,感谢您的帮助。【参考方案3】:
这是由于最新版本的猫鼬,您必须使用findOneAndRemove
而不是FindByIdAndRemove
。
那是演员objectId
的问题。
【讨论】:
以上是关于模型“用户”的路径“_id”中值“586cc8b3ea780c071bbe2469”的值“586cc8b3ea780c071bbe2469”转换为 ObjectId 失败的主要内容,如果未能解决你的问题,请参考以下文章
CastError:模型“用户”的路径“_id”处的值“未定义”转换为 ObjectId 失败
模型“用户”的路径“_id”处的值“ id: '5f1c64aa177bf9379491ecc8'”转换为 ObjectId 失败
Mongoose CastError:模型“Post”的路径“_id”处的值“未定义”转换为 ObjectId 失败
对于模型的路径“_id”处的值,转换为 ObjectId 失败