Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

トークン認証を設定する

最終更新 Markdown で表示Agent セットアップ

トークン認証を使うと、ユーザー登録なしで、文書、ファイル、メディアへのアクセスを特定の利用者に限定できます。有料コンテンツや閲覧制限のあるコンテンツの無断取得と不正な共有を防ぐのに役立ちます。

トークン認証の設定方法は 2 つあります。Cloudflare Workers を使う方法と、カスタムルールを使う方法です。

オプション 1: Cloudflare Workers で設定する

トークン認証の実装例として、次の Cloudflare Workers の資料を参照してください。

Workers を始めるには、テンプレート を参照してください。

オプション 2: カスタムルールで設定する

Rules 言語の is_timed_hmac_valid_v0() HMAC 検証関数を使い、カスタムルール式でハッシュベースメッセージ認証コード(HMAC)トークンを検証します。

トークン認証を検証するには、ルール式で is_timed_hmac_valid_v0() 関数を呼び出す カスタムルールを作成 します。アクションには Block などを使えます。

ルールの例

この例は、特定のホスト名と URL パスで HMAC キー検証に失敗した訪問者をブロックするルールです。トークン認証に必要な情報は次のとおりです。

  • HMAC の生成と検証に使うシークレットキー(例: mysecrettoken
  • 認証したいパス(例: downloads.example.com/images/cat.jpg
  • トークンを含むクエリ文字列パラメーター名(例: verify
  • トークンの有効期間(秒)(例: 3 時間 = 10,800 秒)

次の URL を例にします。

downloads.example.com/images/cat.jpg?verify=1484063787-9JQB8vP1z0yc5DEBnH6JGWM3mBmvIeMrnnxFi3WtJLE%3D

各部分の意味は次のとおりです。

  • /images/cat.jpg はアセットのパスです。認証対象の HMAC メッセージになります。
  • ?verify= は、アセットのパスと、HMAC トークン発行時のタイムスタンプを区切る区切り文字です。
  • 1484063787 はトークン発行時のタイムスタンプで、UNIX 時間(秒)です。
  • 9JQB8vP1z0yc5DEBnH6JGWM3mBmvIeMrnnxFi3WtJLE%3D は Base64 エンコードされた MAC です。

カスタムルールの式は、次のようになります。

(http.host eq "downloads.example.com" and not is_timed_hmac_valid_v0("mysecrettoken", http.request.uri, 10800, http.request.timestamp.sec, 8))

このカスタムルールの構成要素(前述の URL を使う場合)は次のとおりです。

  • トークンのシークレットキー = mysecrettoken
  • トークンの有効期間 = 10800(10,800 秒 = 3 時間)
  • http.request.uri = /images/cat.jpg?verify=1484063787-9JQB8vP1z0yc5DEBnH6JGWM3mBmvIeMrnnxFi3WtJLE%3D
  • http.request.timestamp.sec = 1484071925(例)
  • 区切り文字の長さ: len("?verify=") = 8

is_timed_hmac_valid_v0() 関数は、mysecrettoken シークレットキーで生成した MAC の値と、http.request.uri にエンコードされた値を比較します。

MAC の値が一致し、かつ次の式のとおりトークンの有効期限が切れていなければ、トークンは有効です。

http.request.timestamp.sec < (<TIMESTAMP_ISSUED> + 10800)

この場合、is_timed_hmac_valid_v0() 関数は true を返します。


HMAC トークンの生成

次の例は、前のセクションで説明したカスタムルールが検証するパス向けに、オリジンサーバーでトークンを生成する方法です。

import hmac
import base64
import time
import urllib.parse
from hashlib import sha256

message = "/images/cat.jpg"
secret = "mysecrettoken"
separator = "verify"
timestamp = str(int(time.time()))
digest = hmac.new((secret).encode('utf8'), "{}{}".format(message, timestamp).encode('utf8'), sha256)
token = urllib.parse.quote_plus(base64.b64encode(digest.digest()))
print("{}={}-{}".format(separator, timestamp, token))
import hmac
import base64
import time
import urllib
from hashlib import sha256

message = "/images/cat.jpg"
secret = "mysecrettoken"
separator = "verify"
timestamp = str(int(time.time()))
digest = hmac.new(secret, message + timestamp, sha256)
param = urllib.urlencode({separator: '%s-%s' % (timestamp, base64.b64encode(digest.digest()))})
print(param)
<?php
$message = "/images/cat.jpg";
$secret = "mysecrettoken";
$separator = "verify";
$timestamp = time();
$token = urlencode(base64_encode(hash_hmac("sha256", $message . $timestamp, $secret, true)));
echo("{$separator}={$timestamp}-{$token}");

JavaScript(JS)または TypeScript(TS)の完全な例は、Workers ドキュメントの Sign requests を参照してください。

この JS / TS の実装例は is_timed_hmac_valid_v0() 関数と互換です。提供されているソースコードで認証したリクエストは、WAF カスタムルールと is_timed_hmac_valid_v0() 関数で検証できます。

次のような URL パラメーターが生成されます。

verify=1484063787-9JQB8vP1z0yc5DEBnH6JGWM3mBmvIeMrnnxFi3WtJLE%3D

このパラメーターを、保護する URL に付加します。

/images/cat.jpg?verify=1484063787-9JQB8vP1z0yc5DEBnH6JGWM3mBmvIeMrnnxFi3WtJLE%3D

生成したトークンパラメーターをテストする

Enterprise プランの場合は、次の手順で、オリジンサーバー上の URL 生成が正しいかを確認できます。

  1. カスタムルールのアクションを Log に設定します。
  2. Security Events のサンプリングログを確認します。

同じシークレットで複数のパスを保護する

同じシークレットキーで、複数の URI パスを保護できます。

前の例では、検証関数の MessageMAC 引数に http.request.uri を渡しています。

http.request.uri にはアセットのパスが含まれ、リクエストごとにその値が取り出されます。そのため、検証関数は同じシークレットキーで、downloads.example.com へのすべてのリクエスト URI を評価します。

同じシークレットキーで複数のパスを認証できますが、認証したいメッセージごとに HMAC トークンを生成する必要があります。

1 つの署名で URI パスプレフィックス全体を保護する

固定長の URI パスプレフィックス全体を、1 つの HMAC 署名で保護できます(シークレットも同じものを使います)。そのためには、is_timed_hmac_valid_v0() 関数の MessageMAC 引数に、完全な URI パスではなく URI パスプレフィックスと、元のクエリ文字列を渡します。

完全な URI パスからプレフィックスを取り出すには、substring() 関数を使います。

次の例では、1 つの HMAC 署名が必要な URI パスプレフィックスは常に 51 文字です(x は文字のプレースホルダーです)。

/case-studies/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/

この場合、長さ 51 の URI パスプレフィックスが変わるたびに、別の HMAC 署名が必要です。

HMAC 検証に失敗したケーススタディファイルへのリクエストをブロックするには、次のようなカスタムルールを作成できます。

ルール式:

  (http.host eq "downloads.example.com" and starts_with(http.request.uri.path, "/case-studies") and not is_timed_hmac_valid_v0("mysecrettoken", concat(substring(http.request.uri.path, 0, 51), "?", http.request.uri.query), 10800, http.request.timestamp.sec, 1))

アクション:

  • Block

有効な受信リクエストの URI パスの例:

/case-studies/12345678-90ab-4cde-f012-3456789abcde/foobar-report.pdf?1755877101-5WOroVcDINdl2%2BQZxZFHJcJ6l%2Fep4HGIrX3DtSXzWO0%3D
/case-studies/12345678-90ab-4cde-f012-3456789abcde/acme-corp.pdf?1755877101-5WOroVcDINdl2%2BQZxZFHJcJ6l%2Fep4HGIrX3DtSXzWO0%3D
/case-studies/768bf477-22d5-4545-857d-b155510119ff/another-company-report.pdf?1755878057-jeMS5S1F3MIgxvL61UmiX4vODiWtuLfcPV6q%2B0Y3Rig%3D

最初の 2 つの URI パスは、カスタムルールが検証する同じ 51 文字のプレフィックス(/case-studies/12345678-90ab-4cde-f012-3456789abcde/)を共有するため、同じ HMAC 署名を使えます。

3 つ目の URI パスはプレフィックスが異なるため、別の HMAC 署名が必要です。

役に立ちましたか?