express-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応
express-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応についてメモしました。
経緯
本番環境でexpress-sessionを利用しセッションの保存先のストアをredisを指定しました。
そして実際にセッションの保存を行った際にエラーにはならないが保存されないという問題が発生しました。
構成
構成としては外側はSSLですが内部はhttpで通信しています。
clinent → proxy(https)
proxy → webアプリ(http)
設定
express-sessionへ渡している設定はこのようになります。
javascriptsession({
secret: 'secret_key',
resave: true,
saveUninitialized: true,
store: new RedisStore({ client: redisClient }),
cookie: {
httpOnly: true,
secure: true,
maxAge: 1000 * 60 * 30,
},
})
環境
- Node 14.15.3
- express 4.17.1
- express-session 1.17.2
- redis 3.1.2
事象の再現手順
下記の手順で再現します。
テスト用のエンドポイント作成
テスト用のエンドポイントを作成してセッションの中身を確認します。
javascriptapp.get(
'/sessin-test',
(req: express.Request, res: express.Response): void => {
console.log(req.session.hoge)
req.session.hoge = "hoge"
console.log(req.session.hoge)
}
);
エンドポイントへリクエスト
エンドポイントへリクエストします。
zsh$ crul https://XXXXXX.XX//sessin-test
ログを確認
ログを確認すると2回目のhogeは出力されています。
console
hoge
再リクエスト
再リクエストを実施するとログは下記になります。
console
hoge
セッションへ保存されているのであれば本来はこのようになって欲しいのですが。
consolehoge
hoge
trust proxyを指定して解決
かなりハマったのですが、proxy下でexpressを利用する場合
trust proxyの設定が必要でした。
expressへtrust proxyをセット
下記のようにexpressへtrust proxyをセットをセットします。
javascriptconst app = express();
app.set("trust proxy", 1);
再度ログを確認
無事セッションが保存されていました。
consolehoge
hoge
原因
cookieのオプションのsecureをtrueにしている場合
javascript cookie: {
secure: true,
},
proxy配下だとexpress自体はhttpで起動しているため信頼できずcookieが発行されないことが原因でした。
app.set( 'trust proxy')を介して「trustproxy」設定を有効にすることにより
expressは、プロキシの背後にあることおよびX-Forwarded- *ヘッダーフィールドが信頼されているという認識へ変わるため
Secureなcookieを発行することができるようになります。
記事Article
もっと見る- article
Dockerの利用していないゴミを掃除しディスクスペースを解放するいくつかのやり方を紹介
- article
Next.js のバンドルサイズを可視化する@next/bundle-analyzer の紹介
- article
VSCodeでTypescriptファイルのimport補完で相対パスではなくエイリアスするための設定
- article
UUIDより短いユニークなIDを生成できるnpmライブラリnanoidの使い方
- article
【解決方法】TypeScript発生したTS2564 エラーの対処
- article
express で IP を取得する際などに利用する req.connection 非推奨(deprecated)の対処