网站的下载防盗链方法讨论

做一个网站,如果还提供了一些文件的下载,那最害怕的就是其他网站的盗链了。不仅没有为网站带来PV,还消耗了大量的流量,完全成了被利用的工具。大站(比如官方网站)往往还不在乎,但作为专门的下载站,防盗链恐怕是首要要考虑的技术问题了。Zblog这方面作的也不够好,大家都知道zblog的上传地址默认为upload了,而且链接直接给出的是真实地址,要防盗链需要做一些改动。

对Asp来说,据我所知两种防盗链的方法比较经典。

1.利用cookie加密
cookie的作用通俗的说就是为访问者做标记,所以这个原理很浅显。只有登陆过主页的人才获得了cookie密钥,密钥可随机生成。而下载页首先要判断用户的cookie是否符合密钥规范,否则认定为外链进入的,不予授权。这种方法的另一个要点是需要使用Response.AddHeader和Server.Transfer来重定向,而不能使用客户端的重定向命令。
实现方法可归纳为两个文件的代码,index.asp和download.asp。

<!---------------index.asp----------------->
<%Response.Buffer = true%>
<HTML>
<HEAD>
</HEAD>
<BODY>
<%
Response.Write 下载地址:<br><br>
Randomize
x = int(rnd()*1000)
Response.Write <a href='download.asp?id= & 1*x & '>要下载的文件名.rar</a>
Response.Cookies(secret) = x
%>
</BODY>
</HTML>

<!---------------download.asp----------------->
<%
Response.Buffer = true
if Request.cookies(secret) = then Response.End
if not Isnumeric(request.cookies(secret)) then Response.End
'这里对传递过来的值没有多加判断,只是为了节省篇幅
secret = clng(Request.Cookies(secret))
id = clng(Request.QueryString(id))
if id/secret = 1 then
         Response.AddHeader content-type,application/x-msdownload
         Response.AddHeader Content-Disposition,attachment;filename=要下载的文件名.rar
Server.Transfer 要下载的文件名.rar
else
Response.Write Error!
end if
%>

2.隐藏真实路径
实际上,原理上这时最容易理解的。如果别人无从知道该文件的路径,也就不能得到真实的文件地址,当然就无法盗链了。如何隐藏呢?我们知道,如果我上传得文件为 text.rar ,在zblog中的下载路径为 http://www.winshome.com/upload/text.rar .那么,直接输入这个网址就可以得到该文件了。现在我的目的就是要隐藏upload这个目录名,这样,仅仅一个文件名不足以暴露真实路径。实现示例代码如下:

<%
From_url = Cstr(Request.ServerVariables("HTTP_REFERER"))
Serv_url = Cstr(Request.ServerVariables("SERVER_NAME"))
if mid(From_url,8,len(Serv_url)) <> Serv_url then
response.write "本站不允许盗链!" 
'也可以改成response.redirect "http://www.winshome.com" 将盗链重定向到主页
response.end
end if

Function GetFileName(longname)
while instr(longname,"/")
longname = right(longname,len(longname)-1)
wend
GetFileName = longname
End Function
Dim Stream
Dim Contents
Dim FileName
Dim TrueFileName
Dim FileExt
Const adTypeBinary = 1
FileName = Request.QueryString("FileName")
if FileName = "" Then
  Response.Write "无效文件名!"
  Response.End
End if

Response.AddHeader "content-disposition", "attachment; filename=" & GetFileName(Request.QueryString("FileName"))
Set Stream = server.CreateObject("ADODB.Stream")
Stream.Type = adTypeBinary
Stream.Open

TrueFileName = "/upload/"&FileName

Stream.LoadFromFile Server.MapPath(TrueFileName)
While Not Stream.EOS
  Response.BinaryWrite Stream.Read(1024 * 64)
Wend
Stream.Close
Set Stream = Nothing
Response.Flush
Response.End
%>


上述代码只做了简单的处理,如有必要,可以对不同文件类型的路径作分别处理,比如对红色部分作下面的扩展:

if lcase(right(FileName,3))="pdf" then '设置pdf类型文件目录
TrueFileName = "/The_pdf_file/"&FileName
end if
if lcase(right(FileName,3))="doc" then '设置DOC类型文件目录
TrueFileName = "/My_DOC_file/"&FileName
end if
if lcase(right(FileName,3))="gif" or lcase(right(FileName,3))="jpg" or lcase(right(FileName,3))="png" then
TrueFileName = "/all_images_/"&FileName '设置图像文件目录
end if


还可以设置对图像文件不做下载处理,在response.clear后加入:

if lcase(right(FileName,3))="gif" or lcase(right(FileName,3))="jpg" or lcase(right(FileName,3))="png" then
Response.ContentType = "image/*" '对图像文件不出现下载对话框
else
Response.ContentType = "application/ms-download"
end if


将代码存为down.asp这样,用户将会看到的下载链接是:http://www.winshome.com/down.asp?filename=test.rar ,文件的真正路径完全取决于该文件以及上传路径的设置了。作为zblog,可以通过ftp将上传的文件自定义到一个文件夹,改下down.asp的设置即可。

有人说,如果down.asp的代码被下载,不是什么都泄露了?事实上,代码泄露之后,任何防盗链都失效了,上面的方法只是使盗链者多费一些周折罢了。如果要强化防盗链的效果,还要做代码加密等工作。
前一篇:如何让搜索引擎搜不到(不收录)我的网站?后一篇:Blogger绑定自定义域名的设置方法
发布:Debugger | 分类:代码收集 | 引用本文 | 发表评论 | 返回顶部

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。