LoginSignup
1
0

More than 5 years have passed since last update.

セッションが更新されない件について(セッションDB使用)

Last updated at Posted at 2017-03-28

はじめに

Node.js+セッションDBにてWEBページを構築していたのですが、sessionが更新されない事象があったためその対処法のメモです。
セッションはメモリ上ではなくRDB(PostgreSQL)上に持ちます。PostgreSQLに対してはpgpool-IIを使用してのアクセスとなります。

先に結論

セッションを作成する箇所において

resave : true

resaveをfalseではなくtrueにします。
また、各セッション更新箇所において

req.session.save();

をやめます。
これでセッションが更新されないことは(今のところ)なくなりました。

環境

  • Node.js : v6.10.0
  • PostgreSQL : 9.6
  • pgpool-II : 3.6.1
  • npmパッケージ群
    • pg : 6.1.4
    • express : 4.14.1
    • express-session : 1.15.1
    • connect-pg-simple : 3.1.2

事象説明

ページ構成

URI method 機能
/ GET ログインページを表示
/login POST ユーザIDとパスワードを元にログイン処理を実施
/menu GET ログインOKの場合メニューを表示。メニューはユーザIDによって見れるものと見れないものがある。

ユーザIDとパスワード、およびどのめにゅーを表示させるかの情報(以下、メニュー権限)は全てRDBに保持してます。
POST:/loginでユーザIDとパスワードが一致した場合、メニュー権限をセッションに格納しGET:/menuします。
GET:/menu時にセッションにあるメニュー権限を見て、どのメニューを表示/非表示するかを決めます。

発生事象

【POST:/loginでユーザIDとパスワードが一致した場合、メニュー権限をセッションに格納するが、その後のGET:/menuにて格納したはずのメニュー権限が取得できない(undefinedになる)】
といった事象が発生しました。
※必ず発生する者ではなく、数回に一回発生する程度。

原因調査

POST:/loginにて格納されたメニュー権限をコンソールに出力すると正常なのに、GET:/menu時にはundefinedになっていることから
「RDBへの書き込みが間に合っていない?」
のかと思いました。
しかし、RDBのログ等調べても原因はわからず・・・

その時のセッション関連のソース

app.js
// ・・・(省略)・・・
var pg = require('pg');
var session = require('express-session');
var pgSession = require('connect-pg-simple')(session);
app.use(session({
    store  : new pgSession({
        pg             : pg,
        conString      : 'postgres://postgresql:postgresql@127.0.0.1:5432/database',
        clear_interval : '300'
    }),
    secret : 'secret',
    resave : false,
    saveUninitialized : true,
    rolling : true,
    cookie : {
        httpOnly: false
    }
}));
// ・・・(省略)・・・
login.js
router.get('/', function(req, res, next) {
    // ・・・(省略)・・・
    req.session.menuAuthority = '(取得したRDBの情報)';
    req.session.save();
    // ・・・(省略)・・・
});

上記の箇所以外でもセッションを更新したあとは必ず

req.session.save();

を行うようにしてました。
このせいで先の「RDBへの書き込みが間に合っていない?」が発生してしまっているのでは?と思い、

req.session.save();

をやめる対応を行いました。

修正後のapp.js

app.js
var pg = require('pg');
var session = require('express-session');
var pgSession = require('connect-pg-simple')(session);
app.use(session({
    store  : new pgSession({
        pg             : pg,
        conString      : 'postgres://postgresql:postgresql@127.0.0.1:5432/database',
        clear_interval : '300'
    }),
    secret : 'secret',
    resave : true,          // falseからtrueへ
    saveUninitialized : true,
    rolling : true,
    cookie : {
        httpOnly: false
    }
}));

上記の変更、および各処理において

req.session.save();

をやめたことによりGET:/menuでもメニュー権限をセッションから取得できるようになりました。

その他

「RDBではなくメモリ上で管理したらどうなったか?」
については試してません。(メモリ上なら問題になっていないのではないかと思いますが。。。)

1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0