Nest.js で typeorm session ストアを利用する
Nest.js x Session
Nest.js における session の機能は、express-session
を利用して実装可能です。
$ npm i express-session
$ npm i -D @types/express-session
インストールした express-session
は main.ts
で以下のように記述します。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as session from 'express-session';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.use(
session({
secret: 'my-secret',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000, // 7days
}
}),
);
await app.listen(process.env.PORT || 3000);
}
bootstrap();
session 関数には様々なオプションを指定可能です。
-
secret
: セッション ID に署名をつける際の鍵文字列 -
resave
: セッションデータに変更がなかったとしても セッションのデータを上書き更新します。 -
saveUninitialized
: 初期化されていないセッションも store に保存します。 -
cookie
: クッキーに関連する様々なオプションを指定します。
express session の default store
express session の 標準の store は、開発用です。
公式のリポジトリでも以下のように記載されています。
Warning The default server-side session storage, MemoryStore, is purposely not designed for a production environment. It will leak memory under most conditions, does not scale past a single process, and is meant for debugging and developing.
production で session を利用する際には、何かしらの Session Store 機構を導入する必要があります。
TypeOrm Store を利用する
session store として一番使いやすいのが typeorm ベースの database store かと思います。
まずは、必要なモジュールをインストールします。
$ npm i connect-typeorm
typeorm の エンティティを以下のように作成して、テーブルを作成しましょう。
import {Entity, Column, Index, PrimaryColumn} from "typeorm";
import { ISession } from "connect-typeorm";
@Entity("t_session")
export class Session implements ISession {
@Index()
@Column("bigint")
public expiredAt = Date.now();
@PrimaryColumn("varchar", { length: 255 })
public id = "";
@Column("text")
public json = "";
}
作成したエンティティをベースに main.ts
を以下のように記述します。
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as session from 'express-session';
import {TypeormStore} from "connect-typeorm";
import {Session} from "./entities/session.entity";
import {getConnection} from "typeorm";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
const sessionRepository = getConnection().manager.getRepository(Session);
app.use(
session({
secret: 'my-secret',
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 7 * 24 * 60 * 60 * 1000,
},
store: new TypeormStore().connect(sessionRepository),
}),
);
await app.listen(process.env.PORT || 3000);
}
bootstrap();
TypeormStore には、第一引数にオプションで以下のような値を渡すことが可能です。
-
cleanupLimit
: セッションが新しくなったときに、有効期限が切れたセッションをどの程度保持するか。default は 0 で、調査目的で遡及的に遡るニーズがあれば数値で世代を指定します。 -
limitSubquery
: 一つのクエリで Session の select delete 両方を実施します。 defaults は true ですが、MariaDB などではサブクエリにおける limit 句が利用できない都合から、cleanupLimit を利用する際には false を指定する必要があります。 -
ttl
: セッションの有効期限秒(time to live)。デフォルトはsession.maxAge
で maxAge がない場合 1日となります。
その他の Store
DB ではなく redis を session store として利用する場合には connect-redis
が利用可能です。
その他利用可能な store 情報の一覧は GitHub から確認できます。
Discussion