Cloudflare Worker 重定向剥离身份验证 headers

Cloudflare Worker redirect stripping auth headers

我设置了一个 Cloudflare worker 来重定向到我们的 API 网关,因为我们无法控制 DNS,不能只设置 CNAME。重定向有效,它传递 body 和所有 headers except 授权。它收到它,当我查看工作人员控制台时,它会将其列为已编辑。它还编辑了我传递的 user_key 参数,但它传递了它。

const base = 'https://myurl.com'
const statusCode = 308;

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request))
})

async function handleRequest(request) {
  const url = new URL(request.url);
  const { pathname, search } = url;

  const destinationURL = base + pathname + search;

  return Response.redirect(destinationURL, statusCode);
}

首先,请注意,您看到的编辑内容纯粹是为了在工作人员控制台中显示。这是一项保护敏感机密不被记录的功能,但它不会影响任何实时请求的内容。

现在,关于您的 Worker 实际在做什么:

此工作人员 returns 将 308 重定向响应返回给客户端。然后由客户端跟随重定向,将相同的请求发送到新的 URL.

然后,由客户端决定是否将 Authorization header 发送到新位置——该行为不受 Cloudflare Workers 控制。事实证明,许多客户端在重定向到不同的域名时故意删除 Authorization header。例如,Go HTTP 客户端库就是这样做的,node-fetch recently started doing this as well. (I happen to disagree with this change, for reasons I explained in a comment.)

如果客户端是网络浏览器,那么行为会很复杂。如果 Authorization header 作为 HTTP 基本身份验证的一部分添加到请求中(即浏览器提示用户输入用户名和密码),则 header 将在在重定向之后。但是,如果 Authorization header 是由 client-side JavaScript 代码在调用 fetch() 时提供的,那么 header 将通过重定向保留.

可能解决此问题的最佳方法是:不要使用 3xx 重定向。相反,让 Worker 直接将请求转发给新 URL。也就是说,而不是这个:

  return Response.redirect(destinationURL, statusCode);

试试这个:

  return fetch(destinationURL, request);

使用此代码,客户端将不会收到重定向。相反,Worker 会直接将请求转发给新的 URL,然后将响应转发回客户端。在这种情况下,Worker 充当中间人代理。从客户端的角度来看,没有发生转发,原来的 URL 只是处理了请求。