在使用 @google-cloud/connect-firestore 进行保存的会话数据中添加创建时间
前言
谷歌已经发布了一个指南,指导使用Google App Engine和Firestore进行会话管理。
非常容易理解,但有件令人担忧的事情
Connect-firestore 不会删除旧会话或过期会话。您可以在Google Cloud控制台上删除会话数据,或者实施自动删除策略。如果在会话中使用存储解决方案,如Memcache或Redis,过期的会话将自动删除。
由于从控制台手动删除旧会话很麻烦,因此希望能够自动删除旧会话。简而言之,就是希望能使用Cloud Memorystore或Cloud SQL来实现。然而,由于Connect-firestore将数据保存为JSON字符串的格式,无法使用查询来删除旧会话。因此,这篇文章的内容是在保存数据时添加一个创建时间字段。
为什么一开始就没有创建时间呢?
实际上,有关这个问题已经创建了,但并没有什么特别的情况,目前已经结束。
会话数据清理·问题 #63·googleapis/nodejs-firestore-session
据说:“由于会话数据中包含了有效期限,所以没有必要单独包含创建时间。由于Firestore本身没有自动删除功能,所以这个需求不是很强烈。”
要做的事情 zuò de shì
创建一个继承自FirestoreStore的类,并覆盖set方法。
首先继承FirestoreStore,并重写set方法。
在将数据写入Firestore时,确保包括创建时间,然后导出即可。
import { FirestoreStore, StoreOptions } from "@google-cloud/connect-firestore";
export class FirestoreStoreMod extends FirestoreStore {
constructor(storeOption: StoreOptions) {
super(storeOption);
}
set = async (
sid: string,
session: unknown,
callback?: ((err?: Error | undefined) => void) | undefined
): Promise<void> => {
let sessJson;
try {
sessJson = JSON.stringify(session);
} catch (err) {
if (typeof callback === "function") {
return callback();
}
}
const username: string | null =
(session as any)?.passport?.user?.username || null;
const createdDate = new Date(); // 本当はサーバータイムスタンプの方が良い。
await this.db
.collection(this.kind)
.doc(sid)
.set({
data: sessJson,
createdDate,
username
})
.then(() => {
if (typeof callback === "function") {
callback();
}
});
};
}
引入并使用。
只需在加载会话模块时导入并调用,就像导入和调用指南一样,其他都可以。
import express from "express";
import session from "express-session";
import { Firestore } from "@google-cloud/firestore";
import { FirestoreStoreMod } from "./components/sessionStore";
const app = express();
// jsonの取り扱い用
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const store = new FirestoreStoreMod({
dataset: new Firestore({
projectId: "ebikaniuni",
keyFilename:"opabinia.json",
}),
kind: "sessions",
});
// セッション
app.use(
session({
secret: "same", // dotenv等で別ファイル化+gitignoreに含める
resave: false,
saveUninitialized: false,
cookie: {
maxAge: 1 * 60 * 60 * 100, // ミリ秒で指定
sameSite: "strict", // ドメインが違うなら送信しない。
httpOnly: true, //httpリクエスト以外で送信されない
secure: false, // 本番時は有効にする
},
store,// 上で宣言したstore
})
);
app.listen(3000, () => {
console.log("server is started.");
});

只需要添加一个近期的cron处理,定期批量删除旧会话。
请查阅资料
-
- Firestore でのセッション処理 | Node.js | Google Cloud
-
- Session data cleanup · Issue #63 · googleapis/nodejs-firestore-session
- @google-cloud/connect-firestore documentation