URL トークンの検証を有効化する
最終更新日 2021-06-30
トークンの検証により、期限が定められた URL を作成できます。トークンは、ウェブアプリケーション内で生成され、クエリー文字列の URL に追加されます。リクエストは、オリジンサーバーではなく、Fastly のエッジで認証されます。Fastly がその URL に対するリクエストを受け取ると、コンテンツの配信前にトークンが検証されます。設定可能な期間が過ぎると、トークンは期限切れとなります。
カスタム VCL を追加する
トークンの検証を有効化するには、vcl_recv
という名前の Varnish 設定を作成し、次のサンプルコードを追加してください。
また、時間限定の URL トークンのドキュメントにあるカスタム VCL と Compute@Edge サンプルもご利用いただけます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# only do this once per request
if (fastly.ff.visits_this_service == 0 && req.restarts == 0) {
declare local var.token STRING;
declare local var.token_expiration STRING;
declare local var.token_signature STRING;
declare local var.to_sign STRING;
# extract and remove the token
set var.token = querystring.get(req.url, "token");
set req.url = querystring.filter(req.url, "token");
# make sure there is a token
if (var.token == "") {
error 403;
}
# make sure there is a valid expiration and signature
if (var.token !~ "^(\d{10,11})_([a-f0-9]{40})$") {
error 403;
}
# extract token expiration and signature
set var.token_expiration = re.group.1;
set var.token_signature = re.group.2;
# calculate string to sign
set var.to_sign = req.url + var.token_expiration;
# make sure the signature is valid
if (!digest.secure_is_equal(var.token_signature, regsub(digest.hmac_sha1(digest.base64_decode("YOUR%SECRET%KEY%IN%BASE64%HERE"), var.to_sign), "^0x", ""))) {
error 403;
}
# make sure the expiration time has not elapsed
if (time.is_after(now, std.integer2time(std.atoi(var.token_expiration)))) {
error 410;
}
}
この VCL で使用する独自のキーを生成してください (ここで示されているサンプルキーは、意図的にエラーが発生するようになっています)。VCL での制限により、キーのバイナリー形式に NUL (0x00) バイトを含まないようにしてください。Linux では以下のコマンドを使用します。
1
$ while (b=$(openssl rand -base64 32) ; echo $b; echo $b | base64 -d | hd | grep " 00 " > /dev/null); do :; done | tail -1
macOS では以下のコマンドを使用します。
1
$ while (b=$(openssl rand -base64 32) ; echo $b; echo $b | base64 -D | hexdump | grep " 00 " > /dev/null); do :; done | tail -1
上記のカスタム VCL コードは以下の2点をチェックします。
- 提供された署名が、トークンの署名と一致しているか。
- 現在の時刻が、トークンで指定された有効期限より前であるか。
署名が無効の場合、Varnish は403レスポンスを返します。署名は有効であるものの、有効期限が過ぎている場合、Varnish は410レスポンスを返します。異なるレスポンスコードは、デバッグに役立ちます。
トークン情報
?token=
GET パラメーターにはトークンが入ることを想定しています。トークンは [expiration]_[signature]
の形式を取り、以下のようになります。
1
1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
トークンを使用する完全なリクエスト URL は、以下のようになります。
1
http://www.example.com/foo/bar.html?token=1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
署名の検証
digest.hmac_sha1
にあるキーは、任意の文字列です。この例のものは、以下のコマンドで生成されました。
1
$ openssl rand -base64 32
サンプルキー YOUR%SECRET%KEY%IN%BASE64%HERE
は、利用しようとすると意図的にエラーが発生するようになっています。ランダム生成されたシークレットキーで置換する必要があります。
キーを知っている人は、トークンの検証をバイパスできるため、秘密にしておくことが重要です。
アプリケーションの設定
アプリケーションにカスタムコードを記述し、トークンを生成して Varnish で認証する必要があります。GitHub の トークン関数リポジトリでサンプルを提供しています。リポジトリのサンプルを確認しながらアプリケーションでカスタムトークンの生成方法を学べます。
テスト
設定をテストするには、アプリケーションにより生成されたトークンをクエリー文字列の URL に追加します。例えば、次のようにします。
http://www.example.com/foo/bar.html?token=1441307151_4492f25946a2e8e1414a8bb53dab8a6ba1cf4615
トークンが有効ならば、通常のレスポンスを受け取ります。無効の場合、403レスポンスを受け取ります。
NUL バイトのトラブルシューティング
シークレットキーに NUL バイトが含まれないことを確認してください。Base64-decoded 文字列に NUL バイト (0x00) が含まれている場合、そのバイトとその後のバイトは、レスポンスに含まれません。詳細については、Base64 デコーディングを参照してください。