2

ログインしているユーザーではなく、1 つのページにさまざまなコンテンツを表示しようとしています。

/ページの生成に使用するコードは次のとおりです。

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'
        })
    }
})

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('/');  
    });
});
4

2 に答える 2

3

これは、従来の同期モデルを Node の非同期コールバック駆動モデルに適用しようとするケースです。

データベース クエリが完了した後、 に戻りtrueますが、データベース ドライバーに戻っているだけです。 checkSessionずっと前に戻った。その関数は、存在する場合(および存在しない場合) にundefinedを返すため、ログイン チェックは常にfalse と評価されます。session.user_idfalse

代わりに、ブランドンの提案を使用してcheckSession非同期にするか、ミドルウェア関数を実装することをお勧めします。

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();
    }
}

これで、ミドルウェア関数を使用する 2 つの方法ができました。すべてのリクエストでユーザーを確認したい場合は、アプリに追加するだけです:

app.use(checkLogin);

これで、すべてのリクエストに がreq.currentUser含まれますが、リクエストごとにデータベースからログイン状態をフェッチするというパフォーマンス ヒットが発生します。または、特定のリクエストのユーザー情報のみが必要な場合は、関数をルートに貼り付けます。

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

詳細については、Express のドキュメントを参照してください。

于 2012-07-06T18:25:24.240 に答える
0

checkSession戻り値をチェックして同期関数として使用しようとしているようですがcheckSession、非同期機能、つまりここのコールバックに依存しているため、同期することはできませんdb.collection('users', function (err, collection) ...checkSession非同期になるように変更する必要があります。

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'
          })
      }
    });
})
于 2012-07-06T18:17:33.813 に答える