0
1

More than 1 year has passed since last update.

deta.shのBaseにある予約データ__expiresに関しての注意点

Last updated at Posted at 2022-09-16

結論

  • putなどのメソッドにあるoptionでexpireInの指定をした場合登録される相対時間はサーバーの時間でなく、ローカルの時間。
    そのため、実際に削除される時間は想定よりサーバー時間とローカル時間のずれ分ずれてしまう
  • put、putMany、insertはデータフィールドとoptionでexpireInを指定した場合、optionが優先される
  • updateの場合、
    • set operationで__expiresを指定した場合、データフィールドが優先されてしまう
    • increment operationで__expiresを指定した場合、重複のデータを変更しようとするエラーが発生する

やったこと

Deta Baseの予約データ__expiresに関してJavaScriptで検証を行いました。
確認したdetaのバージョンは以下の通りです。

"dependencies": {
  "deta": "^1.1.0"
}

Deta Baseとは

Deta Baseとはdeta.shのサービスのひとつです。
データを格納することができ、NoSQLデータベースの一種です。

予約データ__expiresとは

Deta Baseのデータを保持する期限です。
Unixタイム時間で管理されており、超えると自動で削除されます。
データを設定する際にoptionとして設定できます。

検証

各章は、実行コード、結果の順に記載していきます。

データフィールドとexpireInオプションを同時に設定した場合

db.put(
  {
    __expires: 1000,
  },
  "data1",
  { expireIn: 100 }
);

__expiresにはopttionで指定した時間が設定されていました。
putMany、insertも同様。

option設定したときに設定される時間はサーバの時間か、ローカルの時間か

db.put(
  {
    __expires: Date.now() / 1000 + 60,
  },
  "data2"
);

db.put(
  {
    data: "data",
  },
  "data3",
  { expireIn: 60 }
);

同じ__expiresが登録されました。
option指定してもローカル時間で登録される模様。

updateのset operationで__expiresをセットした場合

{
  const { __expires } = await db.put(
    {
      __expires: "data",
    },
    "data",
    { expireIn: 600 }
  );
  // putした時の時間:1663328394
  console.log(__expires);
}
{
  const updates = {
    __expires: Date.now() / 1000 + 200,  // 200秒後なので相対的に400秒早い
  };
  await db.update(updates, "data", { expireIn: 600 });
  const { __expires } = await db.get("data");
  // updateした時の時間:1663327994
  console.log(__expires);
}

putした後の時間1663328394からupdateした後の時間1663327994でちょうど400小さくなっている。

updateのincrement operationで__expiresをセットした場合

const updates = {
  __expires: db.util.increment(1000),
};

db.update(updates, "data", { expireIn: 600 });

例外発生

/home/path/to/projet/node_modules/deta/dist/index.js:187
                                error: new Error(message),
                                       ^
Error: Bad request: Conflicting operations on common attribute(s)

まとめ

予約データの__expiresをユーザーが直接いじるのは、悪意があるのでおいておくにしても、
expireInで登録される時間が、サーバー時間でなくローカル時間なのは罠だと思います。

おまけ

データフィールドに__expiresを現在でセットした場合

db.put(
  {
    __expires: Date.now() / 1000,
  },
  "data"
);

確認される前に削除されていました。
自分でもきちんと設定できる模様。

データフィールドの__expiresをStringにした場合

実行コード

db.put(
  {
    __expires: "data",
  },
  "data"
);

例外発生

/home/path/to/project/node_modules/deta/dist/index.js:187
                                error: new Error(message),
                                       ^
Error: Bad expiration timestamp
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1