在使用 @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.");
});

image.png

只需要添加一个近期的cron处理,定期批量删除旧会话。

请查阅资料

    • Firestore でのセッション処理  |  Node.js  |  Google Cloud

 

    • Session data cleanup · Issue #63 · googleapis/nodejs-firestore-session

 

    @google-cloud/connect-firestore documentation
bannerAds