対象読者
- express-sessionでセッション管理を実装したい
- サーバーを再起動するたびにセッション情報が消えてしまって困っている
- redisを使いたい
- connect-redisの使い方がわからない
問題
セッション管理をexpress-sessionでやろうとしたけれど、サーバーを再起動させるたびにセッション情報が消えてしまってました。
デプロイする度にユーザーはログインし直さないといけなくて不便なので、何とかする必要がありました。
解決
Redisを導入して、セッション情報をRedisに格納するようにしました。
npm install redis connect-redis
Redisについて
- メモリ上にデータを保存できる辞書型DB
- express-sessionだけだと、アプリを再起動する度にセッション情報が破棄されてしまう
- が、Redisはexpress-sessionとは独立しているので、影響を受けずにセッション情報は保持されたままになる。
勘違いしていたこと
Node.jsにredisをインストールするんですが、それだけでRedisが使用できると勘違いしてました。。
実際にはアプリとは別にOSにRedisをインストールする必要がありました。
インストール方法はこちらを参照してください。
https://weblabo.oscasierra.net/redis-windows-install/
インストールしたらredis-server.exeでRedisを起動する必要があります。
初期状態ではパスが通っていないので、環境変数でPATHに、C:\Program Files\Redis(Redisがインストールされているパス)を追加するとパスが通って、どこからでもredis-server.exeが実行できるようになります。
redis-server.exe --service-run //--service-runを付けると実行してもコマンドプロンプトが閉じない
//起動したかの確認
redis-cli
ping
//PONGと表示されれば起動の確認OK
これでRedisが使用できる状態になります。
コード実装
app.js
const express = require("express");
const path = require("path");
const cors = require("cors");
const session = require("express-session");
const passport = require("passport");
const RedisStore = require("connect-redis").default;
const { createClient } = require("redis");
const redisClient = createClient();
redisClient.connect().catch(console.error);
const redisStore = new RedisStore({
client: redisClient,
});
const dotenv = require("dotenv");
const envFile = process.env.NODE_ENV ? `.env.${process.env.NODE_ENV}` : ".env";
dotenv.config({ path: envFile });
const app = express();
// セッションを開始したときのクッキーへの送信とRedisへの登録の設定
app.use(
session({
secret: process.env.SESSION_SECRET_KEY,
resave: false,
saveUninitialized: true,
cookie: { maxAge: Number(process.env.SESSION_COOKIE_MAX_AGE) },
store: redisStore,
})
);
app.use(passport.initialize());
app.use(passport.session());
これでうまく行きました。
connect-redisの扱いは情報が錯乱していたので、本家のドキュメントを参考にするといいです。
まとめ
これでサーバーアプリの再起動やデプロイをしたときなどでも、セッション情報がリセットされることがなくなって、ユーザーフレンドリーになりました。