3

connect-redisモジュールをセッションストアとしてテストする単純なnode.jsサーバーがあります。それはすべて機能しますが、私は新しいsessを取得することに気づきました:すべてのリクエストでredisのキーを入力します。セッションが1つしかないため、キーは1つしか期待していませんでした。

複数のsessを示すredis-cli:キー

これが私のコードです:

var connect = require('connect');
var util = require("util");
var RedisStore = require("connect-redis")(connect);
var http = require('http');

var app = connect()
  .use(connect.cookieParser('keyboard cat'))
  .use(connect.query())
  .use(connect.session( {
      secret:"elms",
      store:new RedisStore({prefix:'sid_'}),
      cookie:{maxAge:60000, secure:false}
    }))
  .use(function(req, res, next) {
    var sess = req.session;
    if (sess.views) {
      res.setHeader('Content-Type', 'text/html');
      res.write("<p>" + util.inspect(req.cookies) + "</p>");
      sess.basket = sess.basket || {book1:0, book2:0, book3:0};
      if(req.query.buyBook1) {sess.basket.book1 ++;}
      if(req.query.buyBook2) {sess.basket.book2 ++;}
      if(req.query.buyBook3) {sess.basket.book3 ++;}
      if(req.query.expiresession) {
        sess.cookie.maxAge = 0;
      }
      res.write('<p>views: ' + sess.views + '</p>');
      res.write('<ul>\
                  <li>book1 ' + sess.basket.book1 + ' - <a href="/?buyBook1=true">Add</a></li>\
                  <li>book2 ' + sess.basket.book2 + ' - <a href="/?buyBook2=true">Add</a></li>\
                  <li>book3 ' + sess.basket.book3 + ' - <a href="/?buyBook3=true">Add</a></li>\
                </ul>\
                <a href="/?expiresession=true">Expire session</a>');
      res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
      res.write('<p>httpOnly: ' + sess.cookie.httpOnly + '</p>');
      res.write('<p>path: ' + sess.cookie.path + '</p>');
      res.write('<p>domain: ' + sess.cookie.domain + '</p>');
      res.write('<p>secure: ' + sess.cookie.secure + '</p>');
      sess.views ++;
    } else {
      sess.views = 1;
    }

    res.write("<p>" + util.inspect(req.cookies) + "</p>");
    res.end('welcome to the session demo. refresh!');
  });
http.createServer(app).listen(3000);

req.session.cookie.domainが常にnullであることに気づきました。私はWindows8を使用しており、hostsファイルを使用して127.0.0.1をwww.gaz-node.comにマップしています。これは、サーバーにあるCookieドメインを想定したものです。関連する可能性があります。

何か案は?ありがとう

4

2 に答える 2

7

答えはとても簡単でした。私はそれをデバッグするためにこの日曜日の朝に特に早く起きました、そして答えは私の最初のコーヒーのマグカップの途中で突然明らかになりました、そしてそれはその後前半よりも美味しかったです。

/favicon.icoリクエストの復讐

/favicon.icoのブラウザからのリクエストを処理していませんでした。これは、私のようなノード初心者にとってはちょっとした落とし穴です。ブラウザがサイトのアイコンを表示できるように、すべてのリクエストの後に/favicon.icoリクエストが続きます(少なくともChromeによる)。favicon.icoを取得するまで諦めません。

実際のセッションは完全に機能しており、そのためのセッションIDは1つしかありませんでしたが、/ favicon.icoのリクエストはCookieを送信せず、リクエストごとに新しいゾンビセッションをトリガーしていました。

これを修正するために、/favicon.icoリクエストを処理して404レスポンスを提供するモジュールを追加しました。執拗なブラウザにファビコンを与えて、代わりに「fs」モジュールを使用して送信することも簡単にできます。

セッションモジュールを使用する前に、next()を呼び出さずに、/ favicon.icoを処理し、応答を終了することが重要です。修正されたコードは次のとおりです。

var connect = require('connect');
var util = require("util");
var RedisStore = require("connect-redis")(connect);
var http = require('http');

var app = connect()
  .use(function(req, res, next) {
    if(req.url == '/favicon.ico') {
      serve404(res);
    } else {
      next();
    } 
  })
  .use(connect.cookieParser())//"elms123"))
  .use(connect.query())
  .use(connect.session( {
      secret:"elms123",
      store:new RedisStore({prefix:'sid_'}),
      cookie:{maxAge:60000, secure:false, domain:"gaz-node.com"}
    }))
  .use(function(req, res, next) {
    var sess = req.session;
    res.setHeader('Content-Type', 'text/html');
    res.write('welcome to the session demo. refresh!');
    if (sess.views) {

      res.write("<p>" + util.inspect(req.cookies) + "</p>");
      sess.basket = sess.basket || {book1:0, book2:0, book3:0};
      if(req.query.buyBook1) {sess.basket.book1 ++;}
      if(req.query.buyBook2) {sess.basket.book2 ++;}
      if(req.query.buyBook3) {sess.basket.book3 ++;}
      if(req.query.expiresession) {sess.cookie.maxAge=0;}
      if(req.query.forceerror) {/*idontexist()*/throw new Error('ahhhh!');}

      res.write('<p>views: ' + sess.views + '</p>');
      res.write('<ul>\
                  <li>book1 ' + sess.basket.book1 + ' - <a href="/?buyBook1=true">Add</a></li>\
                  <li>book2 ' + sess.basket.book2 + ' - <a href="/?buyBook2=true">Add</a></li>\
                  <li>book3 ' + sess.basket.book3 + ' - <a href="/?buyBook3=true">Add</a></li>\
                </ul>\
                <a href="/?expiresession=true">Expire session</a>\
                <a href="/?forceerror=true">Force error</a>');
      res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>');
      res.write('<p>httpOnly: ' + sess.cookie.httpOnly + '</p>');
      res.write('<p>path: ' + sess.cookie.path + '</p>');
      res.write('<p>domain: ' + sess.cookie.domain + '</p>');
      res.write('<p>secure: ' + sess.cookie.secure + '</p>');
      sess.views ++;
    } else {
      sess.views = 1;
    }

    res.end("<p>" + util.inspect(req.cookies) + "</p>");
  })
  .use(connect.errorHandler());
http.createServer(app).listen(3000);

function serve404(res) {
  res.writeHead(404, {"content-type": "text/plain"});
  res.end("Error : Resource not found");
}
于 2013-03-03T08:52:12.790 に答える
0

私もこの問題を抱えていました。もちろん、「ファビコン」ミドルウェアを使用する必要があります。そして、必ず「セッション」ミドルウェアを「静的」の下に配置してください。私の答えを参照してくださいhttps://stackoverflow.com/a/21094838/3190612

于 2014-01-13T15:24:13.380 に答える