express-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応
セキュリティーexpressエラー解消Node.js
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)
}
);
エンドポイントへリクエスト
エンドポイントへリクエストします。
terminalcrul https://XXXXXX.XX//sessin-test
ログを確認
ログを確認すると2回目のhogeは出力されています。
loghoge
再リクエスト
再リクエストを実施するとログは下記になります。
loghoge
セッションへ保存されているのであれば本来はこのようになって欲しいのですが。
loghoge hoge
trust proxyを指定して解決
かなりハマったのですが、proxy下でexpressを利用する場合
trust proxyの設定が必要でした。
expressへtrust proxyをセット
下記のようにexpressへtrust proxyをセットをセットします。
const app = express();
app.set("trust proxy", 1);
再度ログを確認
無事セッションが保存されていました。
loghoge hoge
原因
cookieのオプションのsecureをtrueにしている場合
cookie: {
secure: true,
},
proxy配下だとexpress自体はhttpで起動しているため信頼できずcookieが発行されないことが原因でした。
app.set( 'trust proxy')を介して「trustproxy」設定を有効にすることにより
expressは、プロキシの背後にあることおよびX-Forwarded- *ヘッダーフィールドが信頼されているという認識へ変わるため
Secureなcookieを発行することができるようになります。
終わりに
最後までご覧いただきありがとうございます。
この記事ではexpress-sessionでセッション保存時にエラーにはならないがセッションが保存されない問題の対応について紹介させていただきました。
これからも皆様の開発に役立つ情報を提供していきたいと考えています。
今後ともよろしくお願いいたします。