HTTP请求头referer,防盗链的问题

1,715 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情


问题

项目中有一个查看第三方平台协议的场景。由于协议是第三方提供的,前端需要在用户点击协议名称时,跳转到指定的第三方协议链接页面。最近新对接了个第三方,需要增加他们的协议。

在测试过程中发现个问题:点击跳转连接时,第三方协议链接返回 403 Forbidden,并抛出以下错误:You are denied by bucket referer policy.

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<hr />
<?xml version="1.0" encoding="UTF-8"?>
<Error>
  <Code>AccessDenied</Code>
  <Message>You are denied by bucket referer policy.</Message>
  <RequestId>6666AE0663EA8B3237A5F000</RequestId>
  <HostId>example.oss-cn-beijing.aliyuncs.com</HostId>
  <BucketName>example</BucketName>
</Error>

原因

排查发现,第三方链接使用的是 阿里云对象存储OSS(AliyunOSS),在 OSS 控制台开启了 Referer防盗链

前端在跳转链接时,默认会在被访问的链接请求头上添加 Referer 头。如下图。

由于前端项目的域名没有在 第三方 Referer防盗链 的白名单中,所以在访问时,会抛出错误 AccessDenied, You are denied by bucket referer policy.

解决

方案1️⃣

在 HTML 中添加 <meta name="referrer" content="no-referrer">content 的值有以下几种

属性值描述
no-referrer不发送 HTTP Referer 请求头。
origin只发送当前文档的 origin。
no-referrer-when-downgrade如果请求目标与当前页面一样安全或者更加安全(HTTP(S)→HTTPS),则发送完整 URL;如果请求目标更加不安全(HTTPS→HTTP),则不发送 referrer。默认行为。
origin-when-cross-origin对同源请求发送完整 URL(不含 URL 参数),其他情况下,只发送 origin。
same-origin对同源请求发送完整 URL(不含 URL 参数),其他情况下,请求不包含 referrer 请求头。
strict-origin如果请求目标与当前页面一样安全或者更加安全(HTTP(S)→HTTPS),则发送 origin;如果请求目标更加不安全(HTTPS→HTTP),则不发送 referrer。
strict-origin-when-cross-origin对同源请求发送完整 URL(不含 URL 参数);其他情况下,如果请求目标与当前页面一样安全或者更加安全(HTTP(S)→HTTPS),则发送 origin;如果请求目标更加不安全(HTTPS→HTTP),则不发送 referrer。
unsafe-URL对同源请求和跨源请求发送完整 URL(不含 URL 参数)。

方案2️⃣

如果是使用 a 标签跳转的方式访问页面可以不使用方案1️⃣。

只需要在 a 标签上添加 rel="noreferrer" 属性或 referrerpolicy="no-referrer"

1、<a href="http://www.example.com" rel="noreferrer">example</a>

2、<a href="http://www.example.com" referrerpolicy="no-referrer">example</a>

方案3️⃣

方案1️⃣、方案2️⃣ 都是在服务端防盗链配置允许 referer 为空的时候,才适用。

如果服务端防盗链设置了不允许 referer 字段为空。那么只能让服务端防盗链将我们自己的网站链接配置到防盗链白名单中,来避免 403 Forbidden, AccessDenied 的问题。

referer 字段

referer 请求头包含了当前请求页面的来源页的地址。

eg:网站 www.example.com 跳转到链接 www.example2.com。则 www.example2.com 网站请求的 Request Header 中的 referer 值为 www.example.com

这里 HTTP RequestHeader 中的 Referer,是拼写错误,应该是叫 Referrer,详情可见:HTTP_referer

在浏览器中可以通过 document.referrer 获取当前页面的 referer。

相关链接

🔗 HTTP Referer

🔗 Referrer-Policy

🔗 a 标签的 referrerpolicy 属性

🔗 a 标签的 rel 属性

🔗 OSS防盗链配置及常见错误排查方法

🔗 访问OSS时出现403状态码的排查方法

🔗 设置OSS防盗链后访问OSS资源出现“You are denied by bucket referer policy”错误