express-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応

セキュリティーexpressエラー解消Node.js
express-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応
Memo

express-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応についてメモしました。

経緯

本番環境でexpress-sessionを利用しセッションの保存先のストアをredisを指定しました。
そして実際にセッションの保存を行った際にエラーにはならないが保存されないという問題が発生しました。

構成

構成としては外側はSSLですが内部はhttpで通信しています。

clinent → proxy(https)
proxy → webアプリ(http)

設定

express-sessionへ渡している設定はこのようになります。

session({
  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

事象の再現手順

下記の手順で再現します。

テスト用のエンドポイント作成

テスト用のエンドポイントを作成してセッションの中身を確認します。

app.get(
  '/sessin-test',
  (req: express.Request, res: express.Response): void => {
    console.log(req.session.hoge)
    req.session.hoge = "hoge"
    console.log(req.session.hoge)
  }
);

エンドポイントへリクエスト

エンドポイントへリクエストします。

terminal
crul https://XXXXXX.XX//sessin-test

ログを確認

ログを確認すると2回目のhogeは出力されています。

log
hoge

再リクエスト

再リクエストを実施するとログは下記になります。

log
hoge

セッションへ保存されているのであれば本来はこのようになって欲しいのですが。

log
hoge hoge

trust proxyを指定して解決

かなりハマったのですが、proxy下でexpressを利用する場合
trust proxyの設定が必要でした。

expressへtrust proxyをセット

下記のようにexpressへtrust proxyをセットをセットします。

const app = express();
app.set("trust proxy", 1);

再度ログを確認

無事セッションが保存されていました。

log
hoge hoge

原因

cookieのオプションのsecureをtrueにしている場合

  cookie: {
    secure: true,
  },

proxy配下だとexpress自体はhttpで起動しているため信頼できずcookieが発行されないことが原因でした。

app.set( 'trust proxy')を介して「trustproxy」設定を有効にすることにより
expressは、プロキシの背後にあることおよびX-Forwarded- *ヘッダーフィールドが信頼されているという認識へ変わるため
Secureなcookieを発行することができるようになります。

終わりに

最後までご覧いただきありがとうございます。
この記事ではexpress-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応について紹介させていただきました。

これからも皆様の開発に役立つ情報を提供していきたいと考えています。
今後ともよろしくお願いいたします。