Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js NodeJS-为登录或未登录的用户显示不同的内容_Node.js_Authentication_Express - Fatal编程技术网

Node.js NodeJS-为登录或未登录的用户显示不同的内容

Node.js NodeJS-为登录或未登录的用户显示不同的内容,node.js,authentication,express,Node.js,Authentication,Express,我试图在一个页面上为登录用户而不是用户显示不同的内容 以下是我用于生成/页面的代码: app.get('/',function(req, res){ if (!checkSession(req, res)) { res.render('index.ejs', { title: 'FrontSpeak - blog-based social network' }) } else { res.render('ind

我试图在一个页面上为登录用户而不是用户显示不同的内容

以下是我用于生成/页面的代码:

app.get('/',function(req, res){
    if (!checkSession(req, res)) {
        res.render('index.ejs', {
            title: 'FrontSpeak - blog-based social network'
       })
    } else {
        res.render('index.ejs', {
            title: 'autrhorized'
        })
    }
})
检查会话功能:

function checkSession(req, res) {
if (req.session.user_id) {
    db.collection('users', function (err, collection) {
        collection.findOne({
            _id: new ObjectID(req.session.user_id)
        }, function (err, user) {
            if (user) {
                req.currentUser = user;
                return true;
            } else {
                return false;
            }
        });
    });
} else {
    return false;
}
}
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            if (doc && doc.password == req.body.password) {
                console.log("user found");
                req.session.user_id = doc._id;
            }
            }
        });
    });

});
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            console.log('found user');
            if (doc && doc.password == req.body.password) {
                req.session.user_id = doc._id;
                res.redirect('/');
            };
            res.redirect('/');
        });
    res.redirect('/');  
    });
});
function checkLogin(req, res, next) {
    if (req.session.user_id) {
        db.collection('users', function (err, collection) {
            if (err) return next(err); // handle errors!
            collection.findOne({
                _id: new ObjectID(req.session.user_id)
            }, function (err, user) {
                if (user) {
                    req.currentUser = user;
                } else {
                    req.currentUser = null;
                }
                next();
            });
        });
    } else {
        req.currentUser = null;
        next();
    }
}
登录功能:

function checkSession(req, res) {
if (req.session.user_id) {
    db.collection('users', function (err, collection) {
        collection.findOne({
            _id: new ObjectID(req.session.user_id)
        }, function (err, user) {
            if (user) {
                req.currentUser = user;
                return true;
            } else {
                return false;
            }
        });
    });
} else {
    return false;
}
}
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            if (doc && doc.password == req.body.password) {
                console.log("user found");
                req.session.user_id = doc._id;
            }
            }
        });
    });

});
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            console.log('found user');
            if (doc && doc.password == req.body.password) {
                req.session.user_id = doc._id;
                res.redirect('/');
            };
            res.redirect('/');
        });
    res.redirect('/');  
    });
});
function checkLogin(req, res, next) {
    if (req.session.user_id) {
        db.collection('users', function (err, collection) {
            if (err) return next(err); // handle errors!
            collection.findOne({
                _id: new ObjectID(req.session.user_id)
            }, function (err, user) {
                if (user) {
                    req.currentUser = user;
                } else {
                    req.currentUser = null;
                }
                next();
            });
        });
    } else {
        req.currentUser = null;
        next();
    }
}
所以,它似乎不起作用。但是,我认为这不是显示不同内容的最佳方式。也许有更优雅的方法可以做到这一点?谢谢大家!

更新:新登录功能:

function checkSession(req, res) {
if (req.session.user_id) {
    db.collection('users', function (err, collection) {
        collection.findOne({
            _id: new ObjectID(req.session.user_id)
        }, function (err, user) {
            if (user) {
                req.currentUser = user;
                return true;
            } else {
                return false;
            }
        });
    });
} else {
    return false;
}
}
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            if (doc && doc.password == req.body.password) {
                console.log("user found");
                req.session.user_id = doc._id;
            }
            }
        });
    });

});
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            console.log('found user');
            if (doc && doc.password == req.body.password) {
                req.session.user_id = doc._id;
                res.redirect('/');
            };
            res.redirect('/');
        });
    res.redirect('/');  
    });
});
function checkLogin(req, res, next) {
    if (req.session.user_id) {
        db.collection('users', function (err, collection) {
            if (err) return next(err); // handle errors!
            collection.findOne({
                _id: new ObjectID(req.session.user_id)
            }, function (err, user) {
                if (user) {
                    req.currentUser = user;
                } else {
                    req.currentUser = null;
                }
                next();
            });
        });
    } else {
        req.currentUser = null;
        next();
    }
}

看起来您正试图通过检查其返回值将
checkSession
用作同步函数,但是
checkSession
不能同步,因为它依赖于异步功能,即此处的回调:
db.collection('users',function(err,collection)…
。您需要将
检查会话
修改为异步:

function checkSession(req, res, callback) {
if (req.session.user_id) {
    db.collection('users', function (err, collection) {
        collection.findOne({
            _id: new ObjectID(req.session.user_id)
        }, function (err, user) {
            if (user) {
                req.currentUser = user;
                callback(true);
            } else {
                callback(false);
            }
        });
    });
} else {
    callback(false);
}
}
然后在请求处理程序中异步使用它:

app.get('/',function(req, res){
    checkSession(req, res, function(isUser) {
      if (!isUser) {
          res.render('index.ejs', {
              title: 'FrontSpeak - blog-based social network'
         })
      } else {
          res.render('index.ejs', {
              title: 'autrhorized'
          })
      }
    });
})

这是一个尝试将传统的同步模型应用于节点的异步回调驱动模型的案例

数据库查询完成后,返回
true
,但您只是返回数据库驱动程序。
checkSession
很久以前就返回了。由于如果存在
会话,该函数将返回未定义的值。用户id
(如果没有,则返回
false
),因此登录检查将始终计算为false

相反,您可以使用Brandon的建议使
checkSession
异步,或者我建议实现一个中间件功能:

function checkSession(req, res) {
if (req.session.user_id) {
    db.collection('users', function (err, collection) {
        collection.findOne({
            _id: new ObjectID(req.session.user_id)
        }, function (err, user) {
            if (user) {
                req.currentUser = user;
                return true;
            } else {
                return false;
            }
        });
    });
} else {
    return false;
}
}
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            if (doc && doc.password == req.body.password) {
                console.log("user found");
                req.session.user_id = doc._id;
            }
            }
        });
    });

});
app.post('/', function(req, res){
    db.collection("users", function (err, collection) {
        collection.findOne({ username: req.body.username }, function (err, doc) {
            console.log('found user');
            if (doc && doc.password == req.body.password) {
                req.session.user_id = doc._id;
                res.redirect('/');
            };
            res.redirect('/');
        });
    res.redirect('/');  
    });
});
function checkLogin(req, res, next) {
    if (req.session.user_id) {
        db.collection('users', function (err, collection) {
            if (err) return next(err); // handle errors!
            collection.findOne({
                _id: new ObjectID(req.session.user_id)
            }, function (err, user) {
                if (user) {
                    req.currentUser = user;
                } else {
                    req.currentUser = null;
                }
                next();
            });
        });
    } else {
        req.currentUser = null;
        next();
    }
}
现在您有两种使用中间件功能的方法。如果您想在每个请求中检查用户,只需将其添加到应用程序中:

app.use(checkLogin);
现在,每个请求都会有一个
req.currentUser
,但是您会遇到从数据库中获取每个请求的登录状态的性能问题。或者,如果您只需要某些请求的用户信息,请将该函数粘贴在路由中:

app.get('/', checkLogin, function(req, res) {
    if (req.currentUser) {
        // logged in
    } else {
        // not
    }
});

您可以在中阅读更多信息。

谢谢,我了解中间件,这是一个完美的解决方案。但有一个问题:如果checkLogin返回null,那么get()就可以了不会执行。我需要向已登录和未登录的用户显示内容。
checkLogin
返回什么并不重要。请这样想:当
GET
请求
/
时,
checkLogin
首先运行(因为它是回调列表中的第一个)。它触发一个DB查询,然后函数什么也不返回。当DB调用完成时,回调会触发,分配给
req
,然后调用
next
next
是神奇的调味品:这是Express调用下一个路由处理程序的方式,在这种情况下是
app.get(…)中的匿名函数
line。现在在匿名路由处理程序函数中,您只需检查
req.currentUser==null
并呈现相应的视图。节点无法找到req的会话属性是否重要?移动的app.use(checkLogin);离开app.configure(函数(){}它成功了!谢谢!是的,你必须确保你的中间件函数在会话中间件之后运行。中间件函数按照它们添加的顺序运行,因此如果你的函数是在会话函数之前添加的,那么当你的函数被调用时,
req.Session
显然还不存在。