You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在代码中为跨域请求注入Auth Header以嵌入受API Key保护的外部页面

解决方案

一、C# 后端代理方案(优先选择,无API Key暴露风险)

通过后端作为中间层代理所有iframe请求,由服务器注入API Key并处理307重定向的Cookie逻辑,完全避免前端接触敏感密钥。

实现步骤

  1. 新增代理API端点
    在ASP.NET Core项目中创建控制器,接收前端iframe的所有请求并转发至目标外部站点。
  2. 首次请求注入API Key
    会话内首次请求时,在请求头添加Authorization: Bearer {你的API Key}后发送给外部站点。
  3. 捕获并保存Auth Cookie
    外部站点返回307重定向时,提取Set-Cookie头内容,存储到服务器会话或前端HttpOnly Cookie中。
  4. 后续请求自动携带Cookie
    同一会话的后续请求,代理直接将存储的Auth Cookie添加到请求头,无需重复注入API Key。
  5. 转发响应至前端
    将外部站点的响应(状态码、headers、内容)原样返回,同时配置CORS允许前端域名访问代理端点。

核心代码示例(ASP.NET Core)

[ApiController]
[Route("proxy/{**path}")]
public class ProxyController : ControllerBase
{
    private readonly HttpClient _httpClient;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public ProxyController(HttpClient httpClient, IHttpContextAccessor httpContextAccessor)
    {
        _httpClient = httpClient;
        _httpContextAccessor = httpContextAccessor;
    }

    [AcceptVerbs("GET", "POST", "PUT", "DELETE")]
    public async Task<IActionResult> ProxyRequest(string path)
    {
        var targetUrl = $"https://客户外部网站域名/{path}";
        var requestMessage = new HttpRequestMessage(new HttpMethod(Request.Method), targetUrl);

        // 复制前端请求头(排除敏感项)
        foreach (var header in Request.Headers)
        {
            if (!requestMessage.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) 
                && !requestMessage.Content?.Headers.TryAddWithoutValidation(header.Key, header.Value.ToArray()) ?? false)
            {
                // 忽略添加失败的非必要头
            }
        }

        // 处理认证逻辑
        var authCookie = _httpContextAccessor.HttpContext.Session.GetString("ExternalAuthCookie");
        if (string.IsNullOrEmpty(authCookie))
        {
            requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", "你的API Key");
        }
        else
        {
            requestMessage.Headers.Add("Cookie", authCookie);
        }

        // 发送请求并获取响应
        var response = await _httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);

        // 捕获307重定向的Cookie
        if (response.StatusCode == HttpStatusCode.TemporaryRedirect)
        {
            if (response.Headers.TryGetValues("Set-Cookie", out var setCookies))
            {
                var cookieString = string.Join("; ", setCookies);
                _httpContextAccessor.HttpContext.Session.SetString("ExternalAuthCookie", cookieString);
                // 同步到前端HttpOnly Cookie,持久化会话
                Response.Cookies.Append("ExternalAuthCookie", cookieString, new CookieOptions { HttpOnly = true, Secure = true });
            }
        }

        // 转发响应头
        foreach (var header in response.Headers)
        {
            Response.Headers.TryAdd(header.Key, header.Value.ToArray());
        }
        foreach (var header in response.Content.Headers)
        {
            Response.Headers.TryAdd(header.Key, header.Value.ToArray());
        }

        // 转发响应内容
        var content = await response.Content.ReadAsByteArrayAsync();
        return File(content, response.Content.Headers.ContentType?.ToString());
    }
}

注意事项

  • 配置HttpClient的超时和重定向策略,避免循环重定向。
  • 启用服务器会话(如内存会话或分布式缓存),确保Cookie在会话周期内有效。
  • 配置CORS规则,允许你的前端域名访问/proxy路径。
  • iframe的src直接指向代理端点,例如/proxy/目标页面路径。

二、JavaScript前端方案(存在API Key暴露风险)

仅适用于非高敏感场景,API Key会暴露在前端代码中,可能被浏览器开发者工具捕获。

实现思路:同源中间页 + Service Worker

  1. 创建同源中间页
    在你的域名下创建空白页面(如iframe-proxy.html),负责加载外部站点内容并注册Service Worker。
  2. Service Worker拦截请求
    注册Service Worker拦截所有指向外部站点的请求,首次请求注入API Key,后续请求携带缓存的Auth Cookie。
  3. 处理307重定向Cookie
    拦截307响应并提取Cookie,存储到CacheStorage中,供后续请求使用。

核心代码示例

中间页(iframe-proxy.html)

<!DOCTYPE html>
<html>
<head>
    <script>
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/sw-proxy.js')
                .then(() => console.log('Service Worker 注册成功'))
                .catch(err => console.error('Service Worker 注册失败', err));
        }

        window.addEventListener('load', () => {
            fetch('https://客户外部网站域名/目标页面')
                .then(res => res.text())
                .then(html => {
                    document.body.innerHTML = html;
                    // 修正页面内相对资源路径
                    document.querySelectorAll('script[src], link[href], img[src]').forEach(el => {
                        const attr = el.tagName === 'SCRIPT' || el.tagName === 'IMG' ? 'src' : 'href';
                        if (el[attr] && !el[attr].startsWith('http')) {
                            el[attr] = `https://客户外部网站域名/${el[attr]}`;
                        }
                    });
                });
        });
    </script>
</head>
<body></body>
</html>

Service Worker(sw-proxy.js)

let authCookie = null;

self.addEventListener('fetch', event => {
    const requestUrl = new URL(event.request.url);
    if (requestUrl.hostname !== '客户外部网站域名') return;

    let modifiedRequest = event.request;
    const headers = new Headers(event.request.headers);

    if (!authCookie) {
        // 首次请求注入API Key
        headers.append('Authorization', 'Bearer 你的API Key');
        modifiedRequest = new Request(event.request, { headers });
    } else {
        // 后续请求携带Cookie
        headers.append('Cookie', authCookie);
        modifiedRequest = new Request(event.request, { headers });
    }

    event.respondWith(
        fetch(modifiedRequest)
            .then(response => {
                // 捕获307重定向的Cookie
                if (response.status === 307) {
                    const setCookie = response.headers.get('Set-Cookie');
                    if (setCookie) authCookie = setCookie.split(';')[0];
                }
                return response;
            })
            .catch(err => console.error('代理请求失败', err))
    );
});

注意事项

  • Service Worker必须部署在你的同源域名下,受浏览器同源策略限制。
  • API Key直接写入前端代码,存在泄露风险,不建议用于高安全要求场景。
  • 需处理页面内的相对资源路径,确保所有请求都被Service Worker拦截。

内容的提问来源于stack exchange,提问作者Nathanael de wet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:23:16