首页 > 其他分享 >你不知道的 HTTP Referer

你不知道的 HTTP Referer

时间:2023-07-29 21:05:16浏览次数:36  
标签:HTTP 请求 访问 域名 referer Referer 知道 图片

前言

上周突然发现自己的自己站点的图片全都403了,之前还是好好的,图片咋就全都访问不了呢?由于我每次发文章都是先发了掘金,然后再从掘金拷贝到我自己的站点,这样我就不用在自己的站点去上传图片了,非常方便。

你不知道的 HTTP Referer_HTTP

啥也没干,图片咋就403了呢?估计又是整了什么开源节流,降本增效吧,说白了就是大家都用他站点的图片导致流量费用蹭蹭蹭的往上涨,人家肯定不愿意了,这下给图片都加上防盗了,非自己的站点全都给你返回403.

防盗原理

是不是很好奇这些图片防盗是怎么做的?

我们可以自己来实现一下这个场景:不受信任的域名访问我服务器上的图片资源全都返回403

准备几个域名

这里没有域名也不用担心,我们可以直接本地模拟就行了,比如我这里使用SwitchHosts给本地添加的三个域名并且都指向我们的本地IP

你不知道的 HTTP Referer_HTTPS_02

这样的话这三个域名都能够访问我们的本地服务了。

服务端逻辑

静态资源目录

这里就用之前的nest服务来做演示,之前我们在这个服务上指定了静态资源目录

app.useStaticAssets(join(__dirname, '../static'), {
  prefix: '/static',
}); // 静态资源

前端访问图片

<img class="my_img" src="http://nanjiu.com:3000/static/sy.jpg" />

这里是使用nanjiu.com代理域名来访问的,图片能够正常访问

你不知道的 HTTP Referer_HTTPS_03

防盗中间件

这里我们可以来实现一个全局中间件用来处理图片的访问,当访问域名不在我们信任的白名单内直接给他返回403

// 白名单
const whiteList = ['nanjiu.com', 'fenanjiu.com']
 // 图片防盗中间件
function imgMiddleware(req, res, next) {
  console.log('--req', req.headers)
  
  // 获取资源类型
  const type = req.headers.accept || ''
  if(!type.includes('image')) {
    // 不是图片资源,直接放行
    next()
    return
  }

  const referer = req.headers.referer || ''
  // 获取referer的域名
  const { hostname } = url.parse(referer, true)
  if(referer && whiteList.includes(hostname) || !referer) {
    // 访问域名在白名单内,放行 !referer表示直接访问图片(比如浏览器地址栏输入图片地址)
    res.status(200)
    next() 
  }else {
    // 访问域名不在白名单内,返回403
    res.status(403)
    res.send('逮到你了,又来偷我图片是吧!')
  }
  
}

这里需要注意的是,全局中间件在使用时一定要在useStaticAssets之前

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  
  app.setGlobalPrefix('api'); // 全局路由前缀
  app.use(cors()); // 允许跨域
  app.use(json({ limit: '10mb' })); // 允许上传大文件
  app.use(urlencoded({ extended: true, limit: '10mb' })); // 允许上传大文件
  app.use(imgMiddleware) // 图片防盗中间件
  app.useStaticAssets(join(__dirname, '../static'), {
    prefix: '/static',
  }); // 静态资源
  
  await app.listen(3000);
  console.log(`Application is running on: ${await app.getUrl()}`);
}
bootstrap();

这上面的代码中我们可以看到,现在受信任的域名就只有nanjiu.comfenanjiu.com

当前端页面使用sy.com这个域名去访问nanjiu.com域名下的图片时,此时应该是会进入防盗逻辑,返回403

你不知道的 HTTP Referer_请求头_04

并且送他一句

你不知道的 HTTP Referer_HTTP_05

Referer

从上面我们实现的防盗原理来看,这其中最关键的就是referer,那么这个referer到底是什么呢?为什么可以用它来做图片防盗

Referer是什么

MDN解释如下:

Referer 请求头包含了当前请求页面的来源页面的地址,即表示当前页面是通过此来源页面里的链接进入的。服务端一般使用 Referer 请求头识别访问来源,可能会以此进行统计分析、日志记录以及缓存优化等。

从这里我们就大概能知道图片防盗的原理了,服务端可以通过请求头中的Referer来识别访问来源,然后判断应不应该给你返回图片

Referer这个单词实际上是Referrer的错误拼写,这其实是个历史原因,在早期 HTTP 规范当中就存在的拼写错误,后面为了向下兼容,所以将错就错。

拼写错误只有 Request HeadersReferer,在其他地方比如General HeadersJavaScriptDOM 上,都是正确的拼写。

Referrer-Policy

Referrer-Policy 首部用来监管哪些访问来源信息——会在 Referer 中发送——应该被包含在生成的请求当中。

它其实是用来控制 Referer 返回的具体内容的

它有以下属性值:

  • no-referrer: 整个 Referer 首部会被移除。访问来源信息不随着请求一起发送。
  • no-referrer-when-downgrade(默认值): 在没有指定任何策略的情况下用户代理的默认行为。在同等安全级别的情况下,引用页面的地址会被发送 (HTTPS->HTTPS),但是在降级的情况下不会被发送 (HTTPS->HTTP)。
  • origin: 在任何情况下,仅发送文件的源作为引用地址。例如 https://example.com/page.html 会将 https://example.com/ 作为引用地址
  • origin-when-cross-origin: 对于同源的请求,会发送完整的 URL 作为引用地址,但是对于非同源请求仅发送文件的源。
  • same-origin: 对于同源的请求会发送引用地址,但是对于非同源请求则不发送引用地址信息。
  • strict-origin: 在同等安全级别的情况下,发送文件的源作为引用地址 (HTTPS->HTTPS),但是在降级的情况下不会发送 (HTTPS->HTTP)。
  • strict-origin-when-cross-origin: 对于同源的请求,会发送完整的 URL 作为引用地址;在同等安全级别的情况下,发送文件的源作为引用地址 (HTTPS->HTTPS);在降级的情况下不发送此首部 (HTTPS->HTTP)。
  • unsafe-url: 无论是同源请求还是非同源请求,都发送完整的 URL(移除参数信息之后)作为引用地址。

这么多referrer策略,我们怎么使用呢?

使用

meta标签

我们可以用一个 name 为 referrermeta元素为整个文档设置 referrer 策略

<meta name="referrer" content="no-referrer">

我的个人站点就是使用该方法来解决图片访问403问题的,但需要注意的是,如果你为页面设置了no-referrer策略会导致页面上所有的请求都不会发送referer,使用时需要自己权衡利弊。

rel属性

可以在aarealink标签上通过rel属性来单独指定referrer的策略

<a href="xxx" rel="noreferrer">新地址</a>

referrerpolicy属性

可以在aarealinkimgiframescript标签上通过referrerpolicy属性来单独指定referrer策略

<img class="my_img" referrerpolicy="no-referrer" src="http://nanjiu.com:3000/static/sy.jpg" />

比如上面例子中的这张图片我们加上referrerpolicy="no-referrer"再去访问,页面还是在sy.com这个域名下面

你不知道的 HTTP Referer_前端_06

可以看到请求头中没有携带referer,所以它就能够躲过图片防盗逻辑。

Headers请求头

也可以更改 HTTP 头信息中的 Referer-Policy 值。比如你使用的是 Nginx,则可以设置 add_headers 设置请求头。

add_header Referrer-Policy "no-referrer";

Headers 请求头和其它页面元素属性同时存在时,确定元素的有效策略时的优先顺序是:

  1. 元素级策略
  2. 页面级策略
  3. 浏览器默认

标签:HTTP,请求,访问,域名,referer,Referer,知道,图片
From: https://blog.51cto.com/u_13756259/6895132

相关文章

  • 关于 HTTP 响应头部字段 X-Cache-Akamai
    笔者的一套适合SAPUI5开发人员循序渐进的学习教程里介绍了SAPUI5应用的开发步骤,运行这些应用后,在Chrome开发者工具Network面板里观察到一个请求的ResponseHeader字段名称为X-Cache-Akamai,值为head,这代表Akamai内容分发网络(ContentDeliveryNetwork,CDN)的缓存状态......
  • 为什么使用 CDN 需要 Angular 应用正确返回 HTTP 200 和 404 状态码
    CDN(ContentDeliveryNetwork)是内容分发网络,它的目的是通过在各地建立节点缓存数据,使用户可以就近获取数据,从而提高数据获取的速度和稳定性。Angular是一种用于构建客户端应用的开发平台。它带来了一种新的方式来构建应用,完全是在浏览器中运行,无需借助任何后端服务。HTTP200......
  • Angular 服务器端渲染应用返回 HTTP 404 和 200 状态码对 SEO 的影响
    在理解为什么Angular应用在正确的时间点返回HTTP404状态码对SEO非常重要之前,我们首先需要了解一些基本的SEO(搜索引擎优化)概念,以及HTTP404状态码的含义。搜索引擎优化(SEO)是一种通过理解搜索引擎如何工作、什么样的内容受欢迎,以及用户在搜索时会使用什么样的关键词......
  • 在 ASP.NET Core 中使用 IHttpClientFactory 发出 HTTP 请求(官方文档)
    在ASP.NETCore中使用IHttpClientFactory发出HTTP请求项目2023/04/11本文内容消耗模式发出POST、PUT和DELETE请求出站请求中间件使用基于Polly的处理程序作者:KirkLarkin、SteveGordon、GlennCondron和RyanNowak。可以注册IHttpClientFactory并将其......
  • AJAX--XMLHttpRequest对象
    一、了解XMLHttpRequest对象是AJAX的核心对象,发送对象以及接收服务器数据的返回XMLHttpRequest对象浏览器都内置了该对象,直接使用二、XMLHttpRequest对象的方法和属性1、创建XMLHttpRequest对象varxhr=newXMLHttpRequest()2、XMLHttpRequest对象的方法方法描述......
  • 关于处理HTTP Get请求ULR过长导致报400错误码的问题
    运行环境:Win11,VS2022现象:使用swagger,Postman发起一个GET请求,返回:HTTPError400.TherequestURLisinvalid. 另外ResponseHeaders中显示Server:Microsoft-HttpApi/2.0原因:是由于Get请求的URL字符串长度过长,导致HTTP.sys服务拦截并终止。解决方案:在注册表项:计算......
  • Oracle数据库DB_NAME、SERVICE_NAME、SID、INSTANCE_NAME、DB_UNIQUE_NAME的区别 转
    Oracle数据库DB_NAME、DBID、DB_UNIQUE_NAME、SERVICE_NAME、SID、INSTANCE_NAME、GLOBAL_DATABASE_NAME的区别DB_NAME:①是数据库名,长度不能超过8个字符,记录在datafile、redolog和controlfile中②在DataGuard环境中DB_NAME相同而DB_UNIQUE_NAME不同③在RAC环境中,各个节点的DB_......
  • 龙蜥白皮书精选:面向 HTTP 3.0 时代的高性能网络协议栈
    文/高性能网络 SIG01背景概述 随着互联网特别是移动互联网的快速发展,对互联网通信协议提出了新的诉求。经过多年的发展,QUIC协议在2021年正式被IEFT标准化,成为HTTP3的标准传输层协议。QUIC是基于UDP实现的面向连接可靠有序的传输协议。相比于TCP在内核态实现,QUIC......
  • AJAX - 创建 XMLHttpRequest 对象
      AJAX-创建XMLHttpRequest对象AJAX(异步JavaScript和XML)是一种在Web应用程序中创建快速动态更新的技术。使用AJAX,Web应用程序可以异步地向服务器发送和接收数据,而无需刷新整个页面。AJAX广泛用于Web应用程序中,包括社交媒体,电子商务,在线游戏等等。XMLHttpRequest是A......
  • android网络通信之HTTP协议教程实…
    在现在的开发和应用中,网络通讯是必不可少的。虽然还是比较怀念小时候,抱着一台95在那里玩单机游戏玩的天昏地暗的时光,但是,现在,就算一个幼儿园的小盆友如果问你要手机玩游戏,突然发现居然买不了冰激凌草莓果汁什么的去喂talkinggina,或者切出一个超爆的水果分数却传不到网上去炫......