【TIPS】特定のコンテンツを指定時間のみアクセス可能にしたい(ワンタイムURLを利用する)

こちらでは、特定のコンテンツを指定時間、アクセス可能なURLを発行する仕組みについて紹介します。

前提条件

  • オリジンサーバ側で、ワンタイムURL対象とするファイルや、ディレクトリのレスポンスヘッダにシークレットキー(X-WebAccel-Secret)を指定する設定が必須となります。
  • オリジンサーバ上の対象コンテンツに直接アクセスされた際のレスポンスヘッダには、シークレットキー(X-WebAccel-Secret)の情報が含まれます。
    第三者にシークレットキーを取得されないためにも、オリジンサーバには、ウェブアクセラレータからのアクセスのみ許可する オリジンガード機能 と併用してご利用下さい。
  • ウェブアクセラレータから配信されるコンテンツのレスポンスヘッダには、シークレットキー(X-WebAccel-Secret)は含まれません。
  • 設定後、シークレットキーを変更した場合、ウェブアクセラレータのコントロールパネルからキャッシュ削除を実行して下さい。キャッシュ削除後から新しいシークレットキーが反映されます。

設定手順

STEP1 事前確認

  • ワンタイムURLの設定を入れる前に、正しくウェブアクセラレータが設定され、キャッシュされているのをご確認ください。
  • 本手順では、STEP4の項目で、オリジンガード機能を設定する様、案内をしておりますが、既にオリジンガードを利用中の場合はスキップして下さい。

STEP2 レスポンスヘッダの設定(オリジンサーバ側での作業)

ワンタイムURL対象のファイルやディレクトリのレスポンスヘッダにシークレットキーを付与する設定を行います。

Apache利用の場合(httpd.confや.htaccess等)

  • さくらのレンタルサーバなど、ウェブサーバ(Apache)の設定ファイルが編集出来ないサーバは、.htaccessへ記述することで利用可能です。
  • シークレットキーは任意の文字列になりますので、第三者に特定されない文字列にされることをお勧め致します。

ファイル対象

  • 以下の例では、対象のファイルが「/images/example.jpg」、シークレットキーを「secretkey」とした場合です。
<Files ~ "example\.jpg$">
  Header set X-WebAccel-Secret "secretkey"
</Files>

ディレクトリ対象

  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、.htaccessに以下の記述を行い、対象ディレクトリ内に設置して下さい。
  • 以下の例では、シークレットキーを「secretkey」とした場合です。
Header set X-WebAccel-Secret "secretkey"

nginx利用の場合

  • シークレットキーは任意の文字列になりますので、第三者に特定されない文字列にされることをお勧め致します。
  • nginxには、locationのプレフィックスに優先順位がありますので、ご注意ください。優先順位を誤りますと、追加分のadd_headerが反映されない事があります。

ファイル対象

  • 以下の例では、対象のファイルが「/images/example.jpg」、シークレットキーを「secretkey」とした場合です。
location = /images/example.jpg {
  add_header x-webaccel-secret "secretkey";
}

ディレクトリ対象

  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、「/images/」といった様に、ディレクトリ名を指定して下さい。
  • 以下の例では、シークレットキーを「secretkey」とした場合です。
location /images/ {
  add_header x-webaccel-secret "secretkey";
}

STEP3 レスポンスヘッダの確認

レスポンスヘッダが正しく設定できているか、オリジンサーバ内で確認します。

確認方法

  • オリジンサーバ上で、以下のコマンドを実行し、X-Webaccel-Secretが表示されるか確認します。
  • 以下の例は、ドメインが「cdn.example.com」、対象ファイルが「/images/example.jpg」、シークレットキーの文字列が「secretkey」の場合です。
# curl -v -o /dev/null -H 'Host: cdn.example.com' http://localhost/images/example.jpg

実行結果

・・ ・・ ・・ ・・ 一部省略 ・・ ・・ ・・ ・・
> GET /images/example.jpg HTTP/1.1     ←対象ファイル
> User-Agent: curl/7.29.0
> Accept: */*
> Host: cdn.example.com            ←対象ドメイン名
>
< HTTP/1.1 200 OK
< Server: nginx/1.13.6
< Date: Fri, 12 Jul 2019 11:27:12 GMT
< Content-Type: image/jpeg
< Content-Length: 108578
< Last-Modified: Fri, 14 Sep 2018 05:59:48 GMT
< Connection: keep-alive
< ETag: "**************"
< x-webaccel-secret: secretkey        ←設定したシークレットキー
< Accept-Ranges: bytes

STEP4 オリジンガード設定

オリジンサーバ上の対象ファイルに直接アクセスした場合、シークレットキー(X-WebAccel-Secret)がレスポンスヘッダに含まれます。
そのため直接オリジンサーバに接続されないよう、 オリジンガード機能 を設定します。

オリジンガード設定後の確認方法

  • オリジンガードが設定された後、オリジンサーバから、以下のコマンドを実行し、X-Webaccel-Secretが表示されず、「403 forbidden」が返されるか確認します。
  • 以下の例は、ドメインが「cdn.example.com」、対象ファイルが「/images/example.jpg」、シークレットキーの文字列が「secretkey」の場合です。
# curl -v -o /dev/null -H 'Host: cdn.example.com' http://localhost/images/example.jpg
上記で「403 forbidden」が返されるか確認して下さい。

STEP5 ワンタイムURLの生成

対象のファイルのワンタイムURLを生成します。
URLは、「シークレットキー」、「対象ファイルのURL」、有効期限を合わせて生成しますので、オリジンサーバ以外でも作成可能です。
よって、ウェブサイトや、ウェブアプリケーションに生成の機能を入れて利用することも可能です。

ワンタイムURL生成例(コマンド入力)

  • 以下の例は、対象のファイルのURLが「 http://cdn.example.com/images/example.jpg 」、シークレットキーの文字列が「secretkey」、有効期限が(2019 年 08 月 31 日 0 時 0 分まで有効)の場合になります。
  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、「/images/」といった様に、ディレクトリ名を指定して下さい。

1.有効期限をUnixTimeで出力します。

# date -d '2019/08/31 00:00:00' +%s
1567177200

2.有効期限をHEX(16進数)に変換。

# printf "%x\n" 1567177200
5d6939f0

3.対象のファイルのパスと有効期限のHEX値、シークレットキーからハッシュ値(MD5)を生成します。

# echo -n "/images/example.jpg/secretkey/5d6939f0" | md5sum
c1f968096a6075053698422c7a6bbb65  -
ファイルパス + シークレットキー + 有効期限をハッシュ値(MD5)にする

4.URLと組み合わせれば有効期限まで有効なワンタイムURLが出来上がります。

形式:
http://example.com/images/example.jpg?hash="MD5の値"&time="HEX値"
URL
http://example.com/images/example.jpg?hash=c1f968096a6075053698422c7a6bbb65&time=5d6939f0

指定した有効期限内に、上記のURLでアクセスを行い、画像が表示されることをご確認下さい。

  • MD5、有効期限のHEXの指定が無い場合、もしくは間違っている場合は、「403 Forbidden」が返されます。
  • 正しいMD5、有効期限のHEXを指定しても、有効期限を過ぎた場合は、「403 Forbidden」が返されます。

ワンタイムURL生成例(スクリプト)

  • 以下の例は、対象のファイルのURLが「 http://cdn.example.com/images/example.jpg 」、シークレットキーの文字列が「secretkey」、有効期限は、下記スクリプト実行の10分後になります。
#!/bin/bash

base_url="http:\/\/cdn\.example\.com"
file_path="/images/example.jpg"
secret="secretkey"
limit_time=$(printf %x $(expr $(date +%s) + 600)) # 10分間(600s)有効

md5=$(echo -n "/$file_path/$secret/$limit_time/" | md5sum)

echo "${base_url}${file_path}?webaccel_secure_time=$limit_time&webaccel_secure_hash=${md5%% *}"

スクリプト実行結果

$ ./create_url.sh ←スクリプトのファイル名は任意です
http:/cdn.example.com/images/example.jpg?webaccel_secure_time=5d2d9453&webaccel_secure_hash=21d498aa696c35431cd2f0240d9eeb3a

指定した有効期限内に、上記のURLでアクセスを行い、画像が表示されることをご確認下さい。

  • MD5、有効期限のHEXの指定が無い場合、もしくは間違っている場合は、「403 Forbidden」が返されます。
  • 正しいMD5、有効期限のHEXを指定しても、有効期限を過ぎた場合は、「403 Forbidden」が返されます。

ワンタイムURL生成例(PHP)

  • 以下の例は、対象のファイルのURLが「 http://cdn.example.com/images/example.jpg 」、シークレットキーの文字列が「secretkey」、有効期限は、下記プログラムの実行の10分後になります。
  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、「/images/」といった様に、ディレクトリ名を指定して下さい。
<?php
$base_url="http://cdn.example.com";
$file_path="/images/example.jpg";
$secret = "secretkey";
$limit_time = sprintf("%08x", time()+600);  // 10分間(600s)有効

echo generateURL($base_url, $file_path, $secret, $limit_time) . "\n";

function generateURL($base_url, $file_path, $secret, $limit_time) {
    $md5 = md5("/" . $file_path . "/" . $secret . "/" . $limit_time ."/" );
    $url = $base_url . $file_path . "?webaccel_secure_time=" . $limit_time . "&webaccel_secure_hash=" . $md5;
    return $url;
}

指定した有効期限内に、上記のURLでアクセスを行い、画像が表示されることをご確認下さい。

  • MD5、有効期限のHEXの指定が無い場合、もしくは間違っている場合は、「403 Forbidden」が返されます。
  • 正しいMD5、有効期限のHEXを指定しても、有効期限を過ぎた場合は、「403 Forbidden」が返されます。