问题描述:
当前众多网站为了减小服务器访问负担都采用防盗链方式禁止外部网络防问,如QQ,开心网等转载的内容中含有图片的话,则图不能正常显示.
实现方案:
1.java方式
在java 的web应用中除了web-inf目录下的文件不能通过url直接访问外,其他在webapp root下的文件都能通过url直接或者间接下载下来,如css image js等文件,通过url去直接下载别人的js应该是很常见的事了。
对js等文件的下载都是偶尔现象,不会对服务器造成太大压力,但是像mp3、rmvb等大文件就会给服务器造成很大压力,加上baidu google sogou等搜索网站的搜索 被别人大量盗链的数量非常大,这就会导致这些盗链占用很多的带宽,从而导致整个网站变慢。那么怎样能够防止别人盗链呢?
先来介绍一个Http请求头 叫referer,通过下面这句可以取到他的值
- String referer = request.getHeader("referer");
String referer = request.getHeader("referer");
referer是干什么的呢? referer可简单的理解为记录了上一个页面的url,直接从url访问一个页面时它的referer为null。
我们就是通过判断referer中的值来决定要不要让这个客户下载我们的资源,可能大家已经想到了 filter可以很简单的完成这个任务 可简单的由下面代码实现
- public void doFilter(ServletRequest req, ServletResponse resp,
- FilterChain chain) throws IOException, ServletException {
- HttpServletRequest request = request = (HttpServletRequest) req;
- HttpServletResponse response = response = (HttpServletResponse) resp;
- String referer = request.getHeader("referer");
- if(referer == null || isLegalUrl(referer)){
- chain.doFilter(req, resp); //合法referer可继续执行
- }else{
- System.out.println("非法请求来源,转到首页"); //转到登录页面或首页
- }
- }
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = request = (HttpServletRequest) req;
HttpServletResponse response = response = (HttpServletResponse) resp;
String referer = request.getHeader("referer");
if(referer == null || isLegalUrl(referer)){
chain.doFilter(req, resp); //合法referer可继续执行
}else{
System.out.println("非法请求来源,转到首页"); //转到登录页面或首页
}
}
很简单的一个过滤器 在web.xml中配置一下, 马上试试吧
- <filter>
- <filter-name>ResourceAccessFilter</filter-name>
- <filter-class>com.redgateonline.daren.web.filter.ResourceAccessFilter</filter-class>
- </filter>
- <filter-mapping>
- <filter-name>ResourceAccessFilter</filter-name>
- <url-pattern>*.mp3</url-pattern>
- </filter-mapping>
<filter>
<filter-name>ResourceAccessFilter</filter-name>
<filter-class>com.redgateonline.daren.web.filter.ResourceAccessFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ResourceAccessFilter</filter-name>
<url-pattern>*.mp3</url-pattern>
</filter-mapping>
启动两个web app 在 webapp1 webapp2, 在webapp1中加一个超链接 下载webapp2的文件
- <a href="http://localhost:8080/webapp2/sss.mp3">下载</a>
<a href="http://localhost:8080/webapp2/sss.mp3">下载</a>
ok 准备工作都做好了 点击 ‘下载’。。。
令人惊讶的是居然弹出了下载对话框, 难道拦截器没起作用,看了一下输出:
- 非法请求来源,转到首页
非法请求来源,转到首页
就是说拦截器起作用了, 侥幸心理让我点击下载对话框的‘保存’,没准在在保存的时候会失败呢 嘿嘿
结果是令人失望的-----保存成功了。
问题出在哪儿呢? 忽然想到文件下载对话框的弹出并不是由我们程序控制的,所以应该在更靠前的地方去拦截请求,至少应该在ie或者ie之前 自然而然想到了apache,apache是直接对端口进行监听的 所有的请求进来后遇到的第一个关卡就是apache,所有在这儿对请求进行拦截应该没有错, 有错没错 试试再说 :)
见四楼
2.php方式
看了一下apache 的文档 有url重写的配置
配置很简单, 把下面这句的#号去掉就可以了
- #LoadModule rewrite_module modules/mod_rewrite.so
#LoadModule rewrite_module modules/mod_rewrite.so
这样apache就添加了url重写功能了
然后在你的虚拟机配置段下添加
- <VirtualHost *:80>
- DocumentRoot C:/eclipseworkspace/daren/web
- ServerName www.webapp2.com
- //以下是配置url重写
- RewriteEngine on
- RewriteCond %{HTTP_REFERER} !^$
- RewriteCond %{HTTP_REFERER} !^http://www.webapp2.com/demo/.*$ [NC] //NC是忽略大小写
- RewriteRule /.(mp3)$ http://www.sohu.com [R=301,L] //R是redirect L是link
- </VirtualHost>
<VirtualHost *:80>
DocumentRoot C:/eclipseworkspace/daren/web
ServerName www.webapp2.com
//以下是配置url重写
RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://www.webapp2.com/demo/.*$ [NC] //NC是忽略大小写
RewriteRule /.(mp3)$ http://www.sohu.com [R=301,L] //R是redirect L是link
</VirtualHost>
RewriteEngine on 打开url重写引擎
RewriteCond url重写条件
- RewriteCond %{HTTP_REFERER} !^$
- RewriteCond %{HTTP_REFERER} !^http://www.webapp2.com/demo/.*$ [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://www.webapp2.com/demo/.*$ [NC]
这两句的意思是 如果referer字段不为空 并且(默认是并且,也可用[OR])不匹配^http://www.webapp2.com/demo/.*$这个正则模式就执行RewriteRule
- RewriteRule /.(mp3)$ http://www.sohu.com [R=301,L]
RewriteRule /.(mp3)$ http://www.sohu.com [R=301,L]
这句的意思是如果url是以.mp3结尾,就redirect到http://www.sohu.com
这样我们就可以有效的防止别人盗链,上面只是应用了mp3文件 扩展一下可以应用到任何文件。
有一个问题是referer能不能人为修改,如果referer能够很简单的修改 那么我们做的这些工作将变得毫无意义