2

本番サーバーのコードにかなり奇妙な問題があります。MacOSでは完全に機能しますが、アプリをデプロイするとログインできません。デバッグ後、req-objectからセッションをロードできないことがわかりました。すべての主要部分のコードは次のとおりです(設定、、ログインページおよびログイン後のメインページ)

//SETTINGS
var express = require('express');
var app = express.createServer();
var mongo = require('mongodb'),
    Server = mongo.Server,
    Db = mongo.Db,
    ObjectID = require('mongodb').ObjectID;
var BSON = require('mongodb').BSONPure;

var RedisStore = require('connect-redis')(express);

//connecting to mongo
var server = new Server('localhost', 27017, {
    auto_reconnect: true
});
var db = new Db('metadocs-node_db', server);

//setting express app
app.set('view engine', 'ejs');
app.configure(function () {
    app.use("/static", express.static(__dirname + '/static'));
    app.use(express.bodyParser());
    app.use(express.cookieParser());
    app.use(express.session({
        secret: "meta-meta",
        store: new RedisStore
    }));
    app.use(express.methodOverride());
});

//login page - POST for /login page
app.post('/login', 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) {
                req.session.user_id = doc._id;
                res.redirect('/');
            } else {
                res.render('login.ejs', {
                    success_login: 1
                });
            }
        });
    });
});

//GET INDEX PAGE - only after login
app.get('/', loadUser, function (req, res) {
    db.collection("companies", function (err, collection) {
        collection.count(function (err, count) {
            res.render('index.ejs', {
                total_companies: count,
                current_user: req.currentUser['username']
            });
        });
    });
});

//loadUser() is function that creates/loads user session if possible
function loadUser(req, res, next) {
    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;
                    next();
                } else {
                    res.redirect('/login');
                }
            });
        });
    } else {
        res.redirect('/login');
    }
}

問題のコード行は次のとおりです。

if (req.session.user_id) {

loadUser()関数で。問題は、req.session.user_idが空であるということです–すべての行を段階的にデバッグしているときにそれを見つけました。私が間違っているのは何ですか?私のMacでは動作しますが、Ubuntuでは動作しません。

4

3 に答える 3

5

この同じ問題について、別の投稿でアドレスを指定したサーバーを試しました。クッキーは問題なく設定されています。ログインに成功しました。ただし、私の注意を引いたのは、有効期限です。現在、2012 年 6 月 26 日 23:18 GMT であり、Cookie の有効期限は 2012 年 6 月 27 日 03:18 GMT に設定されており、Cookie の有効期限が切れるまであと 4 時間しかありません。

4 時間で有効期限が切れる Cookie を設定しても問題ありません。サーバーまたはクライアントに間違った日付/時刻またはタイムゾーンが設定されていない限り。動作しているクライアントと動作していないクライアント、そしてもちろんサーバーで正しい日付/時刻とタイムゾーンが設定されていることを確認してください。これがおそらくあなたの問題の理由だと思います。

私が開発したシステムでは、Cookie の有効期限を 1 年間設定しています。Cookieの有効期限に依存せずに、サーバー側でセッションを検証します。私は常に自分でこれらのことを行う方が快適であるため、Cookie とセッション管理には接続を使用しません。ただし、まだ接続を使用しているときに同じことを行うことができます。セッション設定で、Cookie の maxAge をより高い値に設定する必要があります。

以下のコードは、connect のドキュメントからコピーしたものです。3 行目に maxAge パラメータを追加し、有効期限を 1 日に設定しました。

connect().
  .use(connect.cookieParser('keyboard cat'))
  .use(connect.session({ key: 'sid', cookie: { secure: true, maxAge:86400000 }}))

あなたの問題がこれで解決されることを願っています。

于 2012-06-26T23:40:57.497 に答える
0

私が見つけた別の解決策は次のとおりです。Debianを使用している場合は、Redisの最新バージョンをインストールできるように、別のaptitudeソースを入手してください。

この問題により、私は数時間検索に忙しくなりました...

于 2012-07-12T08:46:08.033 に答える
0

ここに私が試してみたいことがいくつかあります:

  1. Ubuntu 10.04 または 10.10 を使用していないことを確認します。

    Ubuntu 10.04 および 10.10 には深刻なバグ (特に 10.10) があり、インスタンスがハングするだけでなく、速度が低下します。http://redis.io/topics/problems

  2. redis サーバー接続をどこで構成していますか? デフォルトではlocalhostに見えると思いますが、本番環境では通常、ホスト/ポート/認証を指定する必要があります(本番環境を所有しているか、サードパーティでホスティングしているかはわかりませんが、これは適用されません。)

  3. no_ready_check フラグも true に設定してみてください。

    client = redis.createClient(port, host, {no_ready_check: true}); 
    client.auth(password, function() { 
        console.log('Redis client connected');
    });
    //then pass client into expressjs like so:
    ...
    store: new RedisStore {client: client}
    
  4. また、「エラー」のイベント ハンドラーを追加し、redis が問題を報告しているかどうかを確認します。

    client.on('error', function (e) {
        console.log(e);
    });
    
  5. 最後に、本番環境の環境変数とローカルホストの開発環境をダンプして、構成に違いがあるかどうかを確認します。開発中にこれらを設定し、本番環境に移行するまでにそれらを忘れることがあります:)

それが役立つことを願っています!

于 2012-06-26T18:53:28.837 に答える