【问题标题】:Populating ref to the parent using Mongoose and displaying complete parent after authentication with passportjs使用 Mongoose 填充对父级的引用并在使用 passportjs 进行身份验证后显示完整的父级
【发布时间】:2014-12-13 15:12:20
【问题描述】:

对于usersp,我有以下架构。 sp 是服务提供者的缩写。服务提供者是一个用户,它对用户有一个引用。 我正在尝试使用 NodeJS 的 PassportJS 模块注册和唱歌。我已经能够注册一个sp,并且我可以在userssps 集合中看到保留在MongoDB 集合中的数据,但是我无法在配置文件页面上显示sp 的完整数据。我只能显示它的用户数据。比如认证后在profile页面看不到spspname数据。

以下是部分代码:

用户架构:

var userSchema = mongoose.Schema({
        ip: String,
        local            : {
            email        : String,
            password     : String
        }
        name: String ,
        created: { type: Date, default: Date.now },
    })
    .plugin(mongooseRole, {
        roles: ['public', 'user', 'sp', 'admin'],
        accessLevels: {
            'public': ['public', 'user', 'sp', 'admin'],
            'anon': ['public'],
            'user': ['user', 'admin'],
            'sp': ['sp', 'admin'],
            'admin': ['admin']
    }
});
var User = mongoose.model("User", userSchema);

sp 架构:

var spSchema = mongoose.Schema({
    user: { type: Schema.ObjectId, ref: 'User' },
    spname: String,
});
var SP = mongoose.model("SP", spSchema);

用于登录的 PassportJS 代码:

//serialization/deserialization code
    // used to serialize the user for the session
    passport.serializeUser(function(user, done) {
        done(null, user.id);
    });

    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            done(err, user);
        });
    });


//authentication code
    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(user.role == 'sp') {
                    SP.findOne({ user: user._id }).populate('user').exec(function(err, sp) {
                        if (err)
                            return done(err);
                        if (!sp.user)
                            return done(null, false, req.flash('loginMessage', 'No sp user found.')); 

                        if (!sp.user.validPassword(password))
                            return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); 
                        return done(null, sp);
                    });
                } 

                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', 'Oops! Wrong password.')); 

                return done(null, user);
            });

        }));

显示个人资料:

app.get('/profile', isLoggedIn, function (req, res) {

    res.render('profile', {
        user: req.user
    });
});

profile.ejs

<%= user %>

有人可以帮助我如何显示整个 sp 对象及其所有数据吗?

【问题讨论】:

    标签: node.js mongodb authentication mongoose-plugins passport.js


    【解决方案1】:

    您只是在反序列化时查询User 架构。如果需要,您需要反序列化 sp。我不完全确定您的情况,但您似乎正在验证 User SP,在这种情况下,您同样应该反序列化User SP(如果User 返回空)。可能是这样的:

    // used to deserialize the user
    passport.deserializeUser(function(id, done) {
        User.findById(id, function(err, user) {
            if (user.role == 'sp')
                SP.findOne({user: user_id}).populate('user').exec(function(err, sp) {
                    done(err, sp);
                });
            else done(err, user);
        });
    });
    

    【讨论】:

    • 感谢反射的回复。我只针对一个集合users 进行身份验证,只有sp 的附加数据在sps 集合中。请告诉我是否可以使用多个表完成身份验证。对用户进行身份验证后,我会检查给定用户是具有user 角色的普通用户,还是具有sp 角色的服务提供者。在您为deserializeUser 回答的代码中,如果没有错误并且找到user,代码是否会在if(!err &amp;&amp; user) return done(err, user); 之后运行?如果找到用户,SP 的数据会不会丢失?
    • 我尝试了以下代码,但它也不起作用:passport.deserializeUser(function(id, done) { User.findById(id, function(err, user) { if(user.role = 'sp') { SP.findOne({user: user_id}).populate('user').exec(function (err, sp) { if (!err) { done(err, sp); } } } done(err, user); }); });我在这里犯了什么错误?
    • @laggingreflexes:我确实试过了,但是没有用。您的回答中有错字,就像我在评论中所说的那样,应该是if (user.role == 'sp') 中的==。谢谢回复。我不确定为什么我仍然只获取用户模式的数据,即使它说它是一个角色为sp 的用户?
    • @skip 第二次查看应该是user.roles。一定要登录console.log(user.roles)?
    • @skip 你还能console.log(user.role)吗?
    猜你喜欢
    • 2017-02-10
    • 1970-01-01
    • 2021-10-11
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 2014-12-08
    • 2018-08-18
    • 1970-01-01
    相关资源
    最近更新 更多