前提:公司是个媒体类网站,对于外网图片要求一些基本的防盗链处理
综合考虑后采用了 .htaccess 配合 网站锁右键 进行一个基本的防盗链处理。
apache如何开启htaccess?
打开httpd.conf(1)
Options FollowSymLinks
AllowOverride None
改为
Options FollowSymLinks
AllowOverride All(2)去掉下面的注释
LoadModule rewrite_module modules/mod_rewrite.so
1. 基本的图片防盗链
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^ [NC]
RewriteCond %{HTTP_REFERER} !bicycling.net.cn [NC]
RewriteCond %{HTTP_REFERER} !cycling-update.cn [NC]
RewriteCond %{HTTP_REFERER} !google.com [NC]
RewriteCond %{HTTP_REFERER} !baidu.com [NC]
RewriteRule .*\.(gif|jpg|jpeg|png)$ http://www.cycling-update.cn/image/logo.png [R,NC,L]
2. 网站禁右键
<script>
document.oncontextmenu=new Function("event.returnValue=false;"); //禁止右键功能,单击右键将无任何反应
</script>
网站禁右键可以很简单通过禁用网页js搞定,然后还是可以右键下载图片,还有种办法通过网页div覆盖,在img上加上另一个div覆盖,但是也可以通过开发人员工具很简单就改掉,所以右键这个办法其实只能防止完全不懂的人,这里不再多写
3. 防止用户直接打开图片进行下载
如果用户有基本的网络知识,上面这2步进行后,用户仍然能够很简单的通过图片源地址打开下载图片。
所以还需要修改 .htaccess 文件
RewriteEngine on
RewriteCond %{HTTP_REFERER} !bicycling.net.cn [NC]
RewriteCond %{HTTP_REFERER} !cycling-update.cn [NC]
RewriteCond %{HTTP_REFERER} !google.com [NC]
RewriteCond %{HTTP_REFERER} !baidu.com [NC]
RewriteRule .*\.(gif|jpg|jpeg|png)$ http://www.cycling-update.cn/image/logo.png [R,NC,L]
//RewriteCond %{HTTP_REFERER} !^ [NC]被去掉了后,用户无法通过源地址直接打开图片
<FilesMatch "\.(gif|jpg|jpeg|png)$">
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
</FilesMatch>
//这一段让网站的图片不会进行缓存,其实考虑到网站用户体验和SEO优化的话,我们往往是会设置成图片缓存时间为1小时左右。但是为了让用户无法复制地址后直接从缓存打开图片,需要设为no-cache
4. 禁止用户通过迅雷、快车等下载工具进行图片下载
做到这一步的时候,普通用户除了进行截图基本没有其他办法可以获取图片,我尝试通过快车下载工具进行原图下载,结果发现能下载,迅雷下载源图也是通过http协议。明明无法打开源地址为什么能下载让我很费解。
网上百度了对应办法,都是通过 User-agent 进行来源软件判断。如下:
RewriteCond %{HTTP_USER_AGENT} ^flashget [NC]
RewriteRule . abuse.txt [L]
但是发现完全没有效果
最后没办法只能查看apache的网站日志文件(var/log/httpd/access_log),发现迅雷下载和快车下载分别为下面2行日志
121.236.105.68 - - [15/Dec/2015:17:38:17 +0800] "GET /data/0000/02/18.jpg HTTP/1.1" 302 227 "http://img.bicycling.net.cn/data/0000/02"
"Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.3; .NET4.0C; .NET4.0E; GWX:RESERVED)"
121.236.105.68 - - [15/Dec/2015:17:38:27 +0800] "GET /data/0000/02/21.jpg HTTP/1.1" 302 227 "http://img.bicycling.net.cn/data/0000/02"
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)"
他们的 User-agent 完全伪装成了浏览器的样子(或者本身就是使用了浏览器的内核进行http数据访问),完全不提及自身的软件名或关键词
但是通过日志文件,发现他们为何能突破我 .htacess 的限定,下面为正常直接打开图片的日志,触发302转址。
121.236.105.68 - - [15/Dec/2015:17:37:47 +0800] "GET /data/0000/02/09.jpg HTTP/1.1" 302 227 "-"
"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.85 Safari/537.36"
而下载工具读取到图片地址后会读取文件夹,通过文件夹读取图片下载,而非直接通过地址打开下载。
所以去掉 RewriteCond %{HTTP_REFERER} !^ [NC] 无法防止下载工具。但是可以通过图片文件夹路径来禁用。
RewriteCond %{HTTP_REFERER} img.bicycling.net.cn/data [NC]
RewriteRule .*\.(gif|jpg|jpeg|png)$ http://www.cycling-update.cn/image/logo.png [R,NC,L]
通过上面4步,基本的图片防盗工作也完成了,但是当我们业务尝试把网页分享到微信朋友圈的时候,会出现无法抓取缩略图的状况,当然是被我们禁止掉了
5. 允许微信分享抓取缩略图
通过读网站日志文件发现微信抓取缩略图的记录如下:
117.81.145.156 - - [21/Dec/2015:11:15:10 +0800] "GET /data/0000/83/taihu_02.jpg HTTP/1.1" 302 227 "-" "Apache-HttpClient/UNAVAILABLE (java 1.4)"
由于这条命令是直接通过url打开图片,所以无法通过referer来打开读取通道,如果通过IP,理论上也可以在做到限定,但是肯定有很多不便,所以最终只能选择通过 User-agent —— “Apache-HttpClient/UNAVAILABLE (java 1.4)”进行通道打开了
最终版 .htaccess 文件如下:
RewriteEngine on
RewriteCond %{HTTP_USER_AGENT} !^Apache-HttpClient/UNAVAILABLE [NC]
RewriteCond %{HTTP_REFERER} !bicycling.net.cn [NC]
RewriteCond %{HTTP_REFERER} !cycling-update.cn [NC]
RewriteCond %{HTTP_REFERER} !google.com [NC]
RewriteCond %{HTTP_REFERER} !baidu.com [NC]
RewriteRule .*\.(gif|jpg|jpeg|png)$ http://www.cycling-update.cn/image/logo.png [R,NC,L]
RewriteCond %{HTTP_REFERER} img.bicycling.net.cn/data [NC]
RewriteRule .*\.(gif|jpg|jpeg|png)$ http://www.cycling-update.cn/image/logo.png [R,NC,L]
<FilesMatch "\.(gif|jpg|jpeg|png)$">
Header set Cache-Control "private, no-cache, no-store, proxy-revalidate, no-transform"
Header set Pragma "no-cache"
</FilesMatch>
补充说明:htaccess文件内置判断默认为 and,而且似乎只能进行一层判断(不可以或的同时与,这个我不是很确定,没去研究)。所以我对图片转址进行了2次分别操作