当前位置:主页   - 电脑 - 网站开发 - ASP.Net
IHttpHandler的妙用(2):防盗链!我的资源只有我的用户才能下载
来源:网络   作者:   更新时间:2012-05-30
收藏此页】    【字号    】    【打印】    【关闭

  昨天也提到了IHttpHandler接口主要有一个IsReusable属性和一个ProcessRequest方法,利用这个方法我们可以处理很多事情的,昨天我们利用了这个方法给图片动态添加了水印,今天我再来展示另一种用法。

  大家查看一个msdn,可以看到它的声明如下:

VisualBasic(声明)
SubProcessRequest(_
  contextAsHttpContext_
)
VisualBasic(用法)
DiminstanceAsIHttpHandler
DimcontextAsHttpContext
instance.ProcessRequest(context)
C#
voidProcessRequest(
  HttpContextcontext
)

  注意这个HttpContext对象,它提供对用于为 HTTP 请求提供服务的内部服务器对象(如 Request、Response、Session 和 Server)的引用。

  有了它我们就方便多了,因为我们的下载资源一般都会有一个下载介绍(假设为details.aspx?id=***),用户查看介绍之后,如果愿意下载,就会点击下载链接,这个链接也是一个页面(假设为download.aspx?id=***),我们就可以得出结论,只要是用户通过我们的网站下载这些资源,那么在下载资源之前访问那个页面(简称前导页,下同)一定是details.aspx,因此我们就可以得出结论只要是下载之前的前导页不是details.aspx这个页面,那个这个下载请求一定是别的网站盗链(其实还可以放宽一点,在下载之前的前导页一定是本站的页面,也还可以要求更紧一点,下载之前访问的页面的id值一定要与下载的id值一致,这就看大家的实际要求了)!

  有了这个推论之后,我们就可以动手写代码了:

usingSystem;
usingSystem.IO;
usingSystem.Web;
///<summary>
///说明:DownloadHandler是一个防盗链的类,它可以防止本站资源被别的网站盗用
///作者:周公
///日期:2008-1-11
///首发地址:http://blog.csdn.net/zhoufoxcn
///</summary>
publicclassDownloadHandler:IHttpHandler
{
  publicDownloadHandler()
  {
    //
    //TODO:在此处添加构造函数逻辑
    //
  }
  #regionIHttpHandler成员
  ///<summary>
  ///指示IHttpHandler实例是否可再次使用
  ///</summary>
  publicboolIsReusable
  {
    get{returntrue;}
  }
  ///<summary>
  ///处理请求的方法
  ///</summary>
  ///<paramname="context">它提供对用于为HTTP请求提供服务的内部服务器对象(如Request、Response、Session和Server)的引用。</param>
  publicvoidProcessRequest(HttpContextcontext)
  {
    UrireferrerUri=context.Request.UrlReferrer;//获取下载之前访问的那个页面的uri
    UricurrentUri=context.Request.Url;
    if(referrerUri==null)//没有前导页,直接访问下载页
    {
      //输出提示,可以根据自身要求完善此处代码
      context.Response.Write("请不要盗链本站资源,请从首页访问。<ahref=http://tech.ddvip.com/2008-11/'index.aspx'>首页</a>");
      return;
    }
    #region判断前导页是否位于本站可以用此段代码
    //if(referrerUri.Host==currentUri.Host)//前导页和当前请求页位于同一个主机
    //{
    //  //用户是通过正常路径访问的,向用户提供下载文件
    //  //实际情况是根据id从数据库找到文件的物理路径,然后输出
    //  //为了简单代码,仅仅演示流程,这里我直接输出了文件
    //  //周公注。2008-1-11
    //  //获取请求的物理文件路径
    //  WriteFile(context);
    //}
    //else
    //{
    //  //输出提示,可以根据自身要求完善此处代码
    //  context.Response.Write("请不要盗链本站资源,请从首页访问。<ahref=http://tech.ddvip.com/2008-11/'index.aspx'>首页</a>");
    //}
    #endregion
    #region判断前导页是否是我们的介绍页面
    stringreferrerPage=referrerUri.LocalPath.Substring(referrerUri.LocalPath.LastIndexOf('/')+1);
    if(referrerPage=="Details.aspx")//如果前导页是我们的介绍页面
    {
      //用户是通过正常路径访问的,向用户提供下载文件
      //实际情况是根据id从数据库找到文件的物理路径,然后输出
      //为了简单代码,仅仅演示流程,这里我直接输出了文件
      //周公注。2008-1-11
      //获取请求的物理文件路径
      WriteFile(context);
    }
    else
    {
      //输出提示,可以根据自身要求完善此处代码
      context.Response.Write("请不要盗链本站资源,请从首页访问。<ahref=http://tech.ddvip.com/2008-11/'index.aspx'>首页</a>");
    }
    #endregion
  }
  privatevoidWriteFile(HttpContextcontext)
  {
    //用户是通过正常路径访问的,向用户提供下载文件
    //实际情况是根据id从数据库找到文件的物理路径,然后输出
    //为了简单代码,仅仅演示流程,这里我直接输出了文件
    //周公注。2008-1-11
    //获取请求的物理文件路径
    stringpath=context.Request.PhysicalPath;
    //注意这里rar文件的ContentType是application/octet-stream
    //不同格式文件的contentType有可能不同
    context.Response.ContentType="application/octet-stream";
    context.Response.WriteFile(path);
  }
  #endregion
}

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明