7.20. データベースを使用した二重サブミット防止

二重サブミット防止 では、サーバ側のトークンはHTTPセッションに保存される。 このため、アプリケーションサーバをスケールアウトする際には、スティッキーセッションやセッションレプリケーション等を 使用する必要がある。

サーバ側のトークンをデータベースに保管する実装を使用することで、特にアプリケーションサーバの設定をしなくても、 複数のアプリケーションサーバ間でトークンを共有できる。

補足

ブラウザが閉じられた場合などにテーブル上にトークンが残ってしまうことがある。 そのため、期限切れのトークンは定期的に削除する必要がある。

重要

HTTPセッションを使用した 二重サブミット防止 はCSRF対策に使用できたが、 本機能はユーザを識別せずにトークンをDBに格納しているためCSRF対策に使用できない。 本機能を使用する場合は、CSRF対策に CSRFトークン検証ハンドラ を使用すること。

7.20.1. 機能概要

サーバ側のトークンをデータベースに保管できる

7.20.2. モジュール一覧

<dependency>
  <groupId>com.nablarch.framework</groupId>
  <artifactId>nablarch-fw-web-doublesubmit-jdbc</artifactId>
</dependency>

7.20.3. 使用方法

データベース上にトークンを保存するためのテーブルが必要となる。

作成するテーブルの定義を以下に示す。

DOUBLE_SUBMISSION テーブル
カラム名 データ型
TOKEN(PK) java.lang.String
CREATED_AT java.sql.Timestamp

テーブル名およびカラム名は変更可能である。 変更する場合は、 DbTokenManager.dbTokenSchemaDbTokenSchema のコンポーネントを定義する。

2種類のコンポーネント定義を追加する。

tokenManager という名前でコンポーネント定義を追加する。 これにより、トークンがデータベースで管理されるようになる。 tokenManager初期化 が必要。

<component name="tokenManager" class="nablarch.common.web.token.DbTokenManager">
  <property name="dbManager">
    <component class="nablarch.core.db.transaction.SimpleDbTransactionManager">
      <property name="dbTransactionName" value="tokenTransaction"/>
    </component>
  </property>
  <!-- 上記のテーブル定義からテーブル名、カラム名を変更する場合のみ以下設定が必要 -->
  <property name="dbTokenSchema">
    <component class="nablarch.common.web.token.DbTokenSchema">
      <property name="tableName" value="DB_TOKEN"/>
      <property name="tokenName" value="VALUE_COL"/>
      <property name="createdAtName" value="CREATED_AT_COL"/>
    </component>
  </property>
</component>

<!-- 初期化が必要なため、以下を設定 -->
<component name="initializer" class="nablarch.core.repository.initialization.BasicApplicationInitializer">
  <property name="initializeList">
    <list>
      <component-ref name="tokenManager"/>
    </list>
  </property>
</component>

tokenGenerator という名前でコンポーネント定義を追加する。 これによりトークンにUUIDが使用され、推測および衝突の可能性を考慮しなくてよくなる。

<component name="tokenGenerator"
           class="nablarch.common.web.token.UUIDV4TokenGenerator" />

重要

テスティングフレームワークのトークン発行 はトークンのDB保存に対応していない。 そのため、自動テスト実行時には HttpSessionTokenManager に差し替えてテストする必要がある。

<!-- トークンをHTTPセッションに保存する -->
<component name="tokenManager" class="nablarch.common.web.token.HttpSessionTokenManager"/>