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

在Cloud Run部署的Node.js React应用中服务端获取认证令牌的正确方法

解决方案:React应用无法直接调用GCP元数据服务器,必须通过后端代理实现

核心结论

你永远无法从浏览器中的React代码直接调用GCP元数据服务器,原因有两点:

  1. 元数据服务器(169.254.169.254)仅对GCP内部计算实例(如Cloud Run、GCE虚拟机)开放,浏览器运行在用户设备上,无法访问这个私有内部地址。
  2. 前端直接处理认证令牌会导致令牌泄露,存在严重安全风险。

正确的做法是:在Node.js后端添加一个代理接口,由后端负责从元数据服务器获取令牌并调用你的Cloud Run服务,再将结果返回给React前端。


步骤1:在Node.js后端添加代理接口

假设你的Node.js项目使用Express框架(若未安装,先执行npm install express cors node-fetch,Node版本≥18可跳过node-fetch):

创建代理路由文件(如routes/graph.js)

const express = require('express');
const router = express.Router();
const fetch = require('node-fetch');

// 代理接口:转发请求到Cloud Run图谱服务
router.get('/api/graph-data', async (req, res) => {
  try {
    // 1. 从元数据服务器获取认证令牌
    const metadataRes = await fetch(
      'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token?audience=<你的Cloud Run服务基础URL>',
      { headers: { 'Metadata-Flavor': 'Google' } }
    );

    if (!metadataRes.ok) throw new Error(`元数据请求失败:${metadataRes.status}`);
    const tokenData = await metadataRes.json();

    // 2. 用令牌调用Cloud Run图谱服务
    const graphRes = await fetch('<你的Cloud Run服务完整URL>', {
      headers: { 'Authorization': `Bearer ${tokenData.access_token}` }
    });

    if (!graphRes.ok) throw new Error(`图谱服务请求失败:${graphRes.status}`);
    const graphData = await graphRes.json();

    res.json(graphData);
  } catch (error) {
    console.error('代理出错:', error);
    res.status(500).json({ error: error.message });
  }
});

module.exports = router;

在主服务器文件(如server.js)中注册路由

const express = require('express');
const cors = require('cors');
const graphRouter = require('./routes/graph');

const app = express();
app.use(cors()); // 允许跨域请求(若前后端同域名可省略)
app.use('/', graphRouter);

const PORT = process.env.PORT || 3001;
app.listen(PORT, () => console.log(`服务器运行在端口${PORT}`));

步骤2:修改React代码调用后端代理

简化getGraphData.js,直接调用后端代理接口,不再处理令牌逻辑:

export const getData = async () => {
  try {
    // 若前后端部署在同一域名,用相对路径;否则用后端完整URL
    const request = await fetch('/api/graph-data');
    if (!request.ok) throw new Error(`请求失败:${request.status}`);
    const data = await request.json();
    console.log("getGraphData.js :: 收到图谱数据", data);
    return data;
  } catch (error) {
    console.log("getGraphData.js :: 获取数据失败", error);
    throw error;
  }
};

步骤3:部署注意事项

  1. 将Node.js后端部署到GCP计算服务(如Cloud Run),确保它能访问元数据服务器。
  2. 给后端服务的服务账号分配roles/run.invoker角色,允许它调用你的Cloud Run图谱服务。
  3. 若前后端分开部署,需配置CORS规则,或把前端静态文件打包到后端服务中一起部署。

替代方案:使用Firebase Auth(针对用户登录场景)

如果你的演示应用需要用户登录后访问,可使用Firebase Auth生成ID令牌,在Cloud Run服务中验证令牌合法性。但如果是无用户的服务到服务认证,后端代理方案是最直接的选择。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 10:35:21