Webサイトによっては掲載する画像を保存できないようにしなければいけない時があります。
今回は画像がダウンロードできないようにするための対策とその回避方法を紹介します。
回避方法に関しては既存のサイトでも使えるかもしれないので、悪用厳禁です!
また、ここに載っている方法は回避可能なので他の方法を検討しなければいけません。
個々の内容は昔からあるテクニックなので何番煎じな内容ですが、まとめ記事として残しておきます。
TL;DR
- フロントエンド: 透明の画像を被せる
- フロントエンド: 右クリックを禁止する
- フロントエンド: ドラッグを禁止する
- バックエンド: 画像のURLから直接アクセスできないようにする
環境
- フロントエンドはChromeで確認しています。
- バックエンドはnginx、Node.jsで確認しています。
- OSはmacOS 10.13で確認しています。
透明の画像を被せる
保存されたくない画像の上に透明の画像をかぶせます。
これで右クリックから画像を保存しても、透明の画像が保存されるようになり画像を守ります。
実装は簡単で同サイズまたはそれより大きいサイズの透明な画像を用意し、z-indexを指定するだけです。
<img src="/images/somepic.png" alt="保存されたくない画像" width="800" height="600"/>
<img src="/images/dummy.png" alt="透明の画像" width="800" height="600" style="z-index: 2"/>
回避方法☠
これは簡単です。
開発者ツール(devTools)のElementsタブを開き、透明の画像を指定しているHTML要素を削除するだけです。
右クリックを禁止する
右クリックをできないようにすることで画像の保存をできないようにします。
これはoncontextmenuにreturn false;
を設定します。
<body oncontextmenu="return false;">
<img src="/images/somepic.png" alt="保存されたくない画像" oncontextmenu="return false;" />
document.oncontextmenu = function(){ return false; };
document.body.oncontextmenu = "return false;"
回避方法☠
JavaScriptでoncontextmenuに設定しているreturn false;
を削除します。
開発者ツール(devTools)のConsoleタブを開き、以下を実行します。
document.oncontextmenu='';
document.body.oncontextmenu='';
ドラッグを禁止する
これは前項の『右クリックを禁止する』と似ています。
onselectstartとonmousedownにreturn false;
を設定します。
<body onselectstart="return false;" onmousedown="return false;">
<img src="/images/somepic.png" alt="保存されたくない画像" onselectstart="return false;" onmousedown="return false;" />
document.onselectstart = function(){ return false; };
document.onmousedown = function(){ return false; };
document.body.onselectstart = "return false;"
document.body.onmousedown = "return false;"
回避方法☠
JavaScriptでonselectstartとonmousedownに設定しているreturn false;
を削除します。
開発者ツール(devTools)のConsoleタブを開き、以下を実行します。
document.onselectstart='';
document.onmousedown='';
document.body.onselectstart='';
document.body.onmousedown='';
画像のURLから直接アクセスできないようにする
まずは画像のURLをそのままブラウザで開いたりcurlやwgetでダウンロードするのを防ぐ方法を紹介します。
バックエンド側で対応します。
Refererでフィルタリングする
Refererが自ドメインで無ければ403を返すようにします。
nginxでの設定は以下の通りです。
location ~* /images/.*\.(jpg|png|gif|jpeg|webp)$ {
valid_referers server_names *.yoursite.com;
if ($invalid_referer) {
return 403;
}
}
Node.jsで行う場合は以下のようにパターンマッチで確認するとよいでしょう。
if (!/^https?.*\.yoursite.com/).test(req.referer) {
res.send(403);
}
回避方法☠
curlやwgetでRefererをリクエスト時に付与するだけです。
curl -OL http://www.yoursite.com/images/sample.png -H "Referer: http://www.yoursite.com"
wget http://www.yoursite.com/images/sample.png --referer=http://www.yoursite.com
参考
あとがき
フロントエンドの技術やリクエストヘッダーなどユーザーが設定できるような方法では画像の保存を防ぐことはできないことがわかりました。
ここに載せた方法以外の対策を行っても絶対に保存できないようにすることは難しいと思います。
インターネットに公開するとはそういうことだと思います。
複数の方法を組み合わせたり、ユーザーが何か操作するたびにoncontextmenuをreturn false;
にするなど工夫して対策するしかないかと思います。
不備、質問、他にも良い方法があればコメント欄かTwitter(@shisama_)にて教えていただければ幸いです。
最後までお読み頂きありがとうございました。