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

为何使用@angular/fire/functions的httpsCallable时Set-Cookie被忽略?

问题分析与解决方案

核心问题

要实现account.topoint.org、experiences.topoint.org等子域间的认证共享,需要让浏览器正确存储跨域请求返回的session Cookie,但当前浏览器未保存返回的Cookie,根源在于三个关键配置缺失:

  • Cookie未指定父域,默认绑定到Cloud Function域名而非topoint.org,导致子域无法访问
  • Angular跨域请求未开启凭证携带,浏览器默认不会保存跨域Cookie
  • CORS配置未允许凭证传递,且请求携带凭证时Access-Control-Allow-Origin不能设为*

修复步骤

1. 修正Cloud Function的Cookie配置

给Cookie添加domain和path属性,确保绑定到父域,所有子域都能访问:

// createSessionToken函数中设置Cookie的部分
const options = {
  maxAge: expiresIn,
  httpOnly: true,
  secure: process.env.FUNCTIONS_EMULATOR === "true" ? false : true,
  domain: ".topoint.org", // 前置点表示所有topoint.org的子域
  path: "/" // 允许所有路径访问该Cookie
};
res.cookie("session", sessionCookie, options);

2. 修正CORS配置

更新handleCors函数,添加允许凭证传递的响应头,同时确保OPTIONS预检请求也返回该头:

const handleCors = (req: Request, res: Response) => {
  const allowedOrigins = ["https://account.topoint.org", "https://experiences.topoint.org", "https://checkout.topoint.org"];
  const origin = req.get("origin") ?? "";

  if (allowedOrigins.includes(origin)) {
    res.set("Access-Control-Allow-Origin", origin);
    res.set("Access-Control-Allow-Credentials", "true"); // 允许凭证传递
  }

  if (process.env.FUNCTIONS_EMULATOR) {
    // 本地开发指定具体前端域名,禁止使用*
    res.set("Access-Control-Allow-Origin", "http://localhost:4200");
    res.set("Access-Control-Allow-Credentials", "true");
  }

  if (req.method === "OPTIONS") {
    res.set("Access-Control-Allow-Methods", "POST, OPTIONS"); // 支持POST请求
    res.set("Access-Control-Allow-Headers", "Authorization, Content-Type");
    res.set("Access-Control-Allow-Credentials", "true"); // OPTIONS预检必须包含该头
    res.set("Access-Control-Max-Age", "3600");
    res.status(204).send("");
    return;
  }
};

3. 修正Angular HttpClient请求配置

在POST请求中添加withCredentials: true,让浏览器保存跨域返回的Cookie:

private async createSessionToken(idToken: string) {
  if (isPlatformServer(this.platformId)) { return; }

  const observable = this.httpClient.post(
    "https://asia-east1-topoint-org.cloudfunctions.net/createSessionToken", // 替换为生产环境Cloud Function域名
    {
      data: {
        idToken: idToken,
      }
    },
    { withCredentials: true } // 关键:开启凭证携带
  );

  observable.subscribe(response => {
    console.log(response);
  });
}

关于httpsCallable的说明

Firebase的httpsCallable默认不支持携带/接收Cookie,因为它基于fetch API且未配置credentials: 'include',因此在需要跨域传递Cookie的场景下,建议直接使用Angular HttpClient。


内容的提问来源于stack exchange,提问作者Jason Rich Darmawan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:41:00