簡単アクセス制限画像配信について
画像を配信する仕組みを考えたとき、
htdocsに画像を配置してしまうとだれでも好きなだけアクセスできてしまいますね。
まぁ、サイトのデザインとかで使っている素材であればいいんですが
ちょっとしたアクセス制限をかけたい素材な場合、
普通にhtdocsに配置して公開すると問題なわけです。
そういうケースの場合は今までMogileFSをつかって
ファイルを管理していたのですが、諸事情によりmogileは使わないで
管理できないかというのを考えてみました。
要件としては
- 素材の管理で冗長構成をとらなくてよい
- アプリ側で認めたファイルだけ提供する
です
個人的にはPerlbalを良く使っているので
Perlbalでためしてみました。
処理の流れとしては、
sv.intraがサービスを提供しているvhostでユーザはこのvhostに対して色々リクエストを投げてくるとします。
sv.intraはplackにより127.0.0.1:5000で動いているとします。
perlbalがport:80でうごいているので、sv.intraにリクエストをなげると
Perlbalが127.0.0.1:5000にreverse_proxyします。
画像ファイルはPerlbalがサーブしており127.0.0.1:7000で待ち受けているとします。
sv.intraはユーザからリクエストがあれば、ユーザにその画像ファイルにアクセスしていいかどうかの判定を行い
画像にアクセスして良い場合はX-REPROXY-URLを返すとします。
Perlbalはsv.intraからうけとったX-REPROXY-URLをみて画像ファイルにreproxyする感じです。
Perlblaの設定ファイル的にはこうなります。
LOAD Vhosts CREATE POOL intra_pool POOL intra_pool ADD 127.0.0.1:5000 CREATE SERVICE intra SET role = reverse_proxy SET pool = intra_pool SET enable_reproxy = true ENABLE intra CREATE SERVICE http_server SET listen = 0.0.0.0:80 SET role = selector SET plugins = Vhosts VHOST sv.intra = intra ENABLE http_server CREATE SERVICE img_server SET listen = 127.0.0.1:7000 SET role = web_server SET docroot = /home/nekokak/imgs SET dirindexing = 0 SET persist_client = on ENABLE img_server
sv.intraのコードはこんな感じです(適当です)
(Perlbal::Plugin::PSGIをつかってもいいかも)
use Plack::Builder; builder { sub { # ここで色々ちぇっくするのですよ! # 画像にアクセスさせてよければX-REPROXY-URLする return [ '200', [ 'Content-Type' => 'image/gif', 'X-REPROXY-URL' => 'http://127.0.0.1:7000/hoge.gif', ], ]; }; };
こうしておけば、ユーザからは画像に直接アクセスすることができず、
sv.intra経由のreproxyでのみ画像ファイルにアクセスさせることができます。
あと、PerlbalじゃなくてもX-REPROXY-URLを解釈できるものであれば(nginxとか)利用可能です。
今思いついて、試して動いたので何か問題点が他にあるかも知れませんがいい感じじゃないかとおもっています。
ユーザが画像とか素材をuploadするケースを考えるとちょっとだるいかもしれませが、
こちら側が提供する画像の配信を管理するのではつかえるんじゃないかなとおもっています。