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

浏览器扩展存储CF服务令牌密钥的安全替代方案探讨

安全访问Cloudflare Zero Trust后n8n Webhook的浏览器扩展方案

针对你的需求,这里提供两个基于Cloudflare生态的安全方案,无需自行搭建后端,同时给出敏感信息存储的最优实践:

方案一:用Cloudflare Workers做请求代理(完全避免扩展存储敏感信息)

这个方案让Workers作为中间层,接管敏感凭证的存储和请求转发,扩展仅调用Workers的公开端点,无需接触任何密钥。

实现步骤:

  1. 创建Cloudflare Worker:在Cloudflare控制台的「Workers & Pages」页面新建Worker。
  2. 配置加密环境变量:在Worker的「Settings → Variables」里添加以下加密变量(点击「Encrypt」确保值不会明文显示):
    • N8N_WEBHOOK_URL:你的n8n实例webhook完整地址
    • CF_SERVICE_TOKEN:Cloudflare服务令牌的完整值(格式为<ID>:<KEY>)
  3. 编写Worker转发逻辑:替换Worker默认代码为以下内容,实现请求转发和权限校验:
export default {
  async fetch(request, env) {
    // 依赖Cloudflare Zero Trust自动校验用户身份
    const userIdentity = request.cf?.access?.identity;
    if (!userIdentity) {
      return new Response("未授权访问", { status: 401 });
    }

    // 解析扩展发送的URL负载
    try {
      const payload = await request.json();
      if (!payload.url) {
        return new Response("缺少URL负载", { status: 400 });
      }

      // 构造转发到n8n的请求
      const n8nRequest = new Request(env.N8N_WEBHOOK_URL, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "Authorization": `Bearer ${env.CF_SERVICE_TOKEN}`
        },
        body: JSON.stringify({ url: payload.url })
      });

      // 转发请求并返回响应
      const response = await fetch(n8nRequest);
      return response;
    } catch (err) {
      return new Response("请求格式错误", { status: 400 });
    }
  }
};
  1. 配置Worker的Zero Trust访问规则:在Cloudflare Zero Trust控制台,给Worker的域名添加访问策略,仅允许你的Gmail账号访问(和n8n实例的认证规则保持一致)。
  2. 扩展端调用Worker:扩展里直接请求Worker的URL,无需存储任何敏感信息,示例代码:
async function sendUrl(url) {
  const response = await fetch("https://your-worker-name.your-username.workers.dev", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ url })
  });
  return await response.json();
}

方案二:扩展集成Cloudflare Zero Trust会话认证(用Cookie访问webhook)

这个方案利用Cloudflare Zero Trust的浏览器会话认证,让用户完成Gmail登录后,扩展通过会话Cookie直接访问n8n webhook,无需存储服务令牌。

实现步骤:

  1. 确认Zero Trust配置:在Cloudflare Zero Trust控制台,确保n8n隧道的访问策略已开启「允许通过浏览器会话访问」,且认证方式为Gmail。
  2. 扩展添加登录入口:在扩展弹窗里添加「登录」按钮,点击后打开n8n隧道的URL引导用户完成认证:
document.getElementById("login-btn").addEventListener("click", () => {
  chrome.tabs.create({ url: "https://your-n8n-tunnel-url.com" });
});
  1. 扩展发送请求时携带会话Cookie:请求n8n webhook时,设置credentials: 'include'来自动携带Zero Trust的会话Cookie,示例代码:
async function sendUrlToN8n(url) {
  try {
    const response = await fetch("https://your-n8n-tunnel-url.com/webhook/your-endpoint", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      credentials: "include", // 携带Zero Trust会话Cookie
      body: JSON.stringify({ url })
    });

    if (!response.ok) throw new Error("请求失败");
    return await response.json();
  } catch (err) {
    console.error("请求错误:", err);
  }
}
  1. 配置扩展主机权限:在manifest.json里添加n8n隧道的主机权限,确保扩展能访问该域名:
"host_permissions": [
  "https://your-n8n-tunnel-url.com/*"
]

敏感信息存储的最优实践(若必须存储)

如果因为特殊场景需要在扩展里存储密钥或webhook地址,绝对不要用未加密的chrome.storage.local,推荐以下方式:

  • 使用会话存储:用chrome.storage.session存储,浏览器关闭后自动清除,适合临时存储会话级数据。
  • 加密后存储:用Web Crypto API对敏感数据加密后,再存入chrome.storage.local,加密密钥可由用户设置的密码生成,示例代码片段:
// 生成AES加密密钥
async function generateEncryptionKey(password) {
  const encoder = new TextEncoder();
  const passwordBytes = encoder.encode(password);
  const keyMaterial = await crypto.subtle.importKey(
    "raw", passwordBytes, { name: "PBKDF2" }, false, ["deriveKey"]
  );
  return crypto.subtle.deriveKey(
    { name: "PBKDF2", salt: encoder.encode("your-salt"), iterations: 100000, hash: "SHA-256" },
    keyMaterial, { name: "AES-GCM", length: 256 }, true, ["encrypt", "decrypt"]
  );
}

// 加密存储数据
async function saveEncryptedData(data, password) {
  const key = await generateEncryptionKey(password);
  const encoder = new TextEncoder();
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const encrypted = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv }, key, encoder.encode(data)
  );
  await chrome.storage.local.set({
    iv: Array.from(iv),
    encryptedData: Array.from(new Uint8Array(encrypted))
  });
}

内容的提问来源于stack exchange,提问作者Zack

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 14:03:21