• ASP.NET Core实现图片防盗链接的功能
  • 发布于 1周前
  • 33 热度
    3 评论
  • 刘棕刃
  • 0 粉丝 12 篇博客
  •   
作为网站开发者,我们有时候不希望自己网站地上的图片被其他网站直接引用。这在某些场景下会导致自己数据中心里巨大的带宽消耗,也就意味着别人使用我们的图片,而我们要为此付钱。例如,你的网站是a.com,你有一张图片是http://a.com/facepalm.jpg,而b.com在他们的网站上使用一个img标签来引用了你的图片,这导致网络请求是进入你的数据中心,消耗你的资源。

许多网站可以屏蔽图片盗链。我这就来教大家如何在ASP.NET或ASP.NET Core应用里实现防盗链。

我所采用的技术是URL重写。我们都知道,每一个HTTP请求都有一些header,其中有一个是“HTTP referer”,你可以在维基百科找到详细介绍(https://en.wikipedia.org/wiki/HTTP_referer)。这同样作用于对图片文件的请求,如果一个图片是被另一个网站所引用的,那么这个请求的header中将包含值为另一个网站域名的HTTP Referer。

在上述的例子里,如果用户访问了b.com的网页看到了http://a.com/facepalm.jpg的图片,对于a.com的网站服务器来说,这个图片请求的http header的referer值将是http://b.com....开头的。这就是我们要检查并阻止的请求。

ASP.NET (.NET Framework) 应用
对于运行在IIS上的传统ASP.NET (.NET Framework)应用,你需要额外安装一个URL Rewrite拓展:https://www.iis.net/downloads/microsoft/url-rewrite

在网站根目录下创建一个UrlRewrite.config文件,内容如下:
<rules>
  <rule name="Prevent Image Hotlinking">
    <match url=".*\.(gif|jpg|png)$"/>
    <conditions>
      <add input="{HTTP_REFERER}" pattern="^$" negate="true"/>
      <add input="{HTTP_REFERER}" pattern="^http://a.com/.*$" negate="true"/>
    </conditions>
    <action type="Rewrite" url="/content/images/no_hotlinking.png"/>
  </rule>
</rules>
这条规则的含义是,遇到.gif, .jpg, .png的图片文件,检查HTTP Referer的header,如果不是以http://a.com开头的,返回事先准备好的图片/content/images/no_hotlinking.png,也就是这个:

接下来,在web.config的system.webServer节点下加入以下片段
<rewrite>
    <rules configSource="UrlRewrite.config" />
</rewrite>

ASP.NET Core 应用
对于ASP.NET Core应用来说,你不需要在托管环境上安装任何额外的东西。

在你的网站根目录下准备一个类似文件UrlRewrite.xml,但有一处不同:你需要将rewrite节点定义为根节点。
<rewrite>
  <rules>
    <rule name="Prevent Image Hotlinking">
      <match url=".*\.(gif|jpg|png)$"/>
      <conditions>
        <add input="{HTTP_REFERER}" pattern="^$" negate="true"/>
        <add input="{HTTP_REFERER}" pattern="^http://a.com/.*$" negate="true"/>
      </conditions>
      <action type="Rewrite" url="/images/no_hotlinking.png"/>
    </rule>
  </rules>
</rewrite>
注意:你需要将这个文件设置为拷贝到输出目录,不然不起作用
<ItemGroup>
  <None Update="UrlRewrite.xml"><CopyToOutputDirectory>Always</CopyToOutputDirectory>
  </None>
</ItemGroup>
打开Startup.cs,将这段代码添加到Configure方法中
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ...
    using (var urlRewriteStreamReader = File.OpenText("UrlRewrite.xml"))
    {
        var options = new RewriteOptions().AddIISUrlRewrite(urlRewriteStreamReader);
        app.UseRewriter(options);
    }
    ...
}
现在,它和上面的ASP.NET Framework的网站一样可以顺利防盗链了!

一些技巧
在真实场景里,网站通常有多个域名以及HTTP/HTTPS多个绑定,甚至还有不同的端口号,就像这样:

生产环境
http://www.dalbll.com
https://www.dalbll.com
开发环境
http://dev.dalbll.com
https://localhost
http://staging.a.com:5000
你不需要逐个手动添加,我们可以利用正则表达式:)

例如,我博客网站的防盗链规则如下:

<add input="{HTTP_REFERER}" pattern="^$" negate="true"/>
<add input="{HTTP_REFERER}" pattern="^https?:\/\/.*dalbll:?\d{0,5}?\/.*$" negate="true"/>
<add input="{HTTP_REFERER}" pattern="^https?:\/\/localhost:?\d{0,5}?\/.*$" negate="true"/>
<add input="{HTTP_REFERER}" pattern="^https?:\/\/.*azurewebsites.net:?\d{0,5}?\/.*$" negate="true"/>
用户评论