はじめに
サーバ一台で稼動するアプリでしたらサーバー内でセッション情報を持たせとけばいいですが、
サーバ複数台に対してELBでリクエストを振り分けるとかなるとそういうわけにもいかなくなります。
セッション情報のためにDBサーバとかRDSとかは仰々しいし、ファイルにしてS3に置くというのも微妙な気がしてたのですが、DynamoDBを使うモジュールがあったので使ってみました。
パッケージインストール
使うのは
の二つですので、
npm install --save express-session connect-dynamodb
でさくっとインストール
余談
express-sessionはセッション情報の保存先に応じて必要なモジュールを追加でインストールするという形式をとっていて、
対応できる範囲はかなり広いです。
app.js内で設定
DynamoDBを使うので当然IAM情報も必要です。
テーブル作ったり書き込んだりするので、権限のあるIAMを用意しときましょう。
var session = require('express-session');
var DynamoDBStore = require('connect-dynamodb')({session: session});
var proxy = require('proxy-agent');
var DynamoDBStoreOptions = {
table: "db-session", //保存先のテーブル名 デフォルトは"sessions"
hashKey: "session-id", //ハッシュキー デフォルトは"id"
prefix: "session", //ハッシュキーに付与するプレフィックス デフォルトは"sess"
AWSConfigJSON: {
region: 'your region',
correctClockSkew: true,
credentials: {
accessKeyId: 'your accessKeyId',
secretAccessKey: 'your secretAccessKey'
},
httpOptions: {
agent: proxy("http://proxyserver.com:8080"), //プロキシ環境下なら必要
//↓二つはDynamoDBのEPROTOエラー回避のため
secureProtocol: 'TLSv1_method',
ciphers: "ALL"
},
},
reapInterval: 24 * 60* 60 * 1000 //セッション情報の保持時間
};
var app = express();
app.use(session({
store: new DynamoDBStore(DynamoDBStoreOptions),
name:'session-name',
secret: 'session-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
//express-sessionを使っているため、httpOnlyオプションはデフォルトでtrue
maxAge: 24 * 60* 60 * 1000,
secure: true
}
}));
こんな感じで設定すればDynamoDB上にセッション情報が保存されるようになりました。
これでELBも怖くありませんね。
おまけ DynamoDBのEPROTOエラーについて
APIでDynamoDBにアクセスすると時折NetworkingError: write EPROTOと怒られることが...
EPROTOってどういうことやねん、プロトコルかよ!
原因がさっぱりわからず、ググッたりAWSの公式に聞いたりしても原因追求には至らず。
公式でも調査対応中のようです。
とりあえずググッた結果及び公式の回答によるとhttpOptionsにsecureProtocol: 'TLSv1_method'とciphers: "ALL"を加えたら怒られなくなったという報告が多いとのことなのでそれに倣っています。
実際に上記オプションを加えてからは再発してないのですが...
うーむ、闇が深い。