Skip to content

ページゲート(開く前の確認・合い言葉)の標準機能化 ​

第1版作成 最終更新 (日本時間)
確認バージョン1.5.8.1

サイトを開いたときに注意事項への同意や合い言葉の入力を求め、通過したら一定時間は聞かない「ページゲート」を、テーブルの管理から設定できる本体の機能にする設計メモです。本体の標準機能ではありません。

拡張スクリプト・拡張スタイル・拡張 SQL だけで作る方法は サイトを開くときに確認ゲートを表示する にあります。すぐに使うならこちらです。

要件 ​

要件内容
同意注意事項を表示し、「理解した」にチェックしないと先へ進めない
合い言葉決められた合い言葉を入力しないと中身を見られない
スキップ一度通過したら一定時間(例: 4 時間)は聞かない
サイト単位特定のサイトだけに設定できる
GUIテーブルの管理から設定できる

拡張機能で作る方式との違い ​

方式手段合い言葉スキップ状態回避のしやすさ
スクリプトだけスクリプトに合い言葉を書き、localStorage で期限を持つブラウザから見えるブラウザごと・利用者が書き換えられるJavaScript を止めれば通れる
拡張 SQL で照合(レシピ)合い言葉をサーバー側で照合する見えない同上同上
本体の機能にする(このページ)サーバーが通過状態を持ち、未通過なら中身を出さない見えないユーザー単位でサーバーに持つ画面の出力をサーバーで止めれば回避できない

サーバースクリプトの「画面表示の前」で context.Redirect() を使って確認ページへ飛ばす方法もありますが(ServerScriptModelContext.cs)、確認ページをプリザンター内に作ると、そのページでもまた同じスクリプトが動くため作りにくくなります。

全体の流れ ​

図を読み込み中…

改修箇所 ​

1. SiteSettings にプロパティを足す ​

csharp
public bool? PageGateEnabled;           // 有効
public string PageGateMessage;          // 注意事項
public bool? PageGateRequireAgreement;  // 同意を必須にする
public bool? PageGateRequirePassphrase; // 合い言葉を必須にする
public string PageGatePassphrase;       // 合い言葉
public int? PageGateSkipMinutes;        // スキップする時間(分)

サイト設定は JSON で保存されるので、public フィールドを足せば保存対象になります。画面から受け取るために Set メソッドの switch にも同じ名前の case を足します。そのまま持つと合い言葉はサイト設定の JSON に平文で残るので、ハッシュにして持つかどうかも決めておきます。

2. テーブルの管理に設定タブを足す ​

SiteUtilities.cs のタブ一覧に #PageGateSettingsEditor を足し、既存の FieldCheckBox・FieldTextBox・FieldMarkDown で入力欄を作ります。

text
テーブルの管理
└── ページゲート(新しいタブ)
    ├── [x] ページゲートを有効にする
    ├── [x] 同意を必須にする
    ├── 注意事項: [Markdown]
    ├── [x] 合い言葉を必須にする
    ├── 合い言葉: [パスワード入力]
    └── スキップする時間(分): [240]

表示名は App_Data/Displays/ に JSON を足し、CodeDefiner で Displays のメソッドを生成します。

3. ゲートのオーバーレイを出力する ​

全画面共通のダイアログ置き場 TemplateDialogs(HtmlTemplates.cs)に、ゲートの HTML を出すメソッドを足します。通過記録が期限内なら何も出しません。

ゲートは閉じるボタンや Esc で閉じられては困るので、jQuery UI Dialog や <ui-modal> ではなく、position: fixed の div を全画面に重ねる形がテーマの世代に関係なく扱いやすくなります。

オーバーレイを重ねるだけでは HTML の中身は送られてしまうので、回避できないようにするには、未通過のときは一覧や編集画面の本体(#MainForm の中身)をサーバー側で出力しない形にします。

4. 通過用のエンドポイント ​

同意と合い言葉を受け取り、サーバーで照合して、通過記録を期限付きで保存するアクションを足します。

csharp
[HttpPost]
public ActionResult SubmitPageGate(long id)
{
    // 1. ss.PageGateEnabled を確認
    // 2. 同意(PageGateRequireAgreement)と合い言葉(PageGatePassphrase)を照合
    // 3. 期限 = 現在 + PageGateSkipMinutes をセッションに保存
    // 4. 成功・失敗を JSON で返す
}

5. スキップ状態をセッションに持つ ​

ユーザー単位で持つと、別のブラウザや端末からでもスキップが効きます。Sessions API の SavePerUser と同じく、セッション ID の代わりに "@" + UserId をキーにして保存します(SessionUtilities.cs)。

項目値
SessionGuid@{UserId}
KeyPageGate_{SiteId} など
Value期限(ISO 8601)

SessionUtilities を使うときの注意点です(1.5.8.1)。

  • Set の userArea: true は、それだけではキーを @{UserId} にしません。sessionGuid に "@" + context.UserId を明示して渡します(SessionUtilities.cs)。
  • userArea: true の値は、Redis を使う設定でも RDB の Sessions テーブルに保存されます(SessionUtilities.cs)。
  • SetUserArea はキーの先頭に User_ を付けます(SessionUtilities.cs)。
  • リクエストごとに読み込まれる context.UserSessionData(@{UserId} の値)は、sessions コントローラー以外では UserArea の値を含みません(Context.cs、SessionUtilities.cs)。userArea: true で保存した通過記録をゲートの判定で読むときは、SessionUtilities.Get(includeUserArea: true, sessionGuid: "@" + context.UserId) のように明示して読みます。

6. ブラウザ側のスクリプト ​

通過ボタンで Ajax を送り、成功ならオーバーレイを外して中身を表示し、失敗ならエラーを表示するだけの小さなスクリプトを足します(generals/ に新しいファイルを作り、index.ts から読み込む)。

改修するファイル ​

ファイル内容種類
Libraries/Settings/SiteSettings.csゲートのプロパティと Set修正
Models/Sites/SiteUtilities.cs設定タブと入力欄修正
Libraries/HtmlParts/HtmlTemplates.csTemplateDialogs からゲートを出す修正
Libraries/HtmlParts/HtmlPageGate.csゲートの HTML新規
Controllers/ItemsController.cs通過用のアクション修正
App_Data/Displays/PageGate*.json表示名・エラーメッセージ新規(CodeDefiner で生成)
Implem.PleasanterFrontend/wwwroot/src/scripts/generals/通過ボタンのスクリプト新規

API とサーバースクリプト ​

ゲートは画面を開く操作に対するもので、API とサーバースクリプトからのアクセスには掛けません。API は自動処理が前提で、対話的な確認に向きません。API の利用は API キーとアクセス権限で制御します。

関連ページ ​

変更履歴

第1版履歴タブと復元・数値項目の通貨記号・画像プレビューモーダルの解説と、編集画面まわりの改修・設計メモを追加