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

如何安全保护Cloud Run API?仅允许Firebase React前端调用

解决方案:安全保护Cloud Run API,仅限你的React前端调用

一、核心原则:绝对禁止客户端持有服务账号密钥

服务账号密钥属于敏感凭据,一旦暴露在前端代码中,任何人都能冒充你的服务账号操作云资源,这是必须严格遵守的安全规则。下面的方案完全不需要客户端存储任何密钥。

二、配置Cloud Run的IAM权限,限制访问范围

  1. 进入Cloud Run控制台,找到你的后端服务,打开「权限」标签页
  2. 移除allUsers权限(如果还存在),确保服务不再公开可访问
  3. 添加以下成员之一,授予**「Cloud Run 调用者」(roles/run.invoker)**权限:
    • 若仅允许经过Firebase Auth登录的用户访问:添加成员allAuthenticatedUsers
    • 若要更严格地限制为你自己Firebase项目下的用户:添加成员principal://iam.googleapis.com/projects/<你的GCP项目ID>/locations/global/workloadIdentityPools/firebase/providers/firebase/google.subject,并设置条件为request.auth.claims.firebase.project_id == "<你的Firebase项目ID>"

三、前端通过Firebase Auth获取合法凭证调用API

利用Firebase Auth生成身份令牌,无需密钥即可完成安全认证:

  1. 确保React项目已集成Firebase Auth(若未集成,先完成初始化配置)
  2. 获取当前登录用户的ID Token:
    async function getIdToken() {
      const user = firebase.auth().currentUser;
      if (!user) {
        throw new Error("用户未登录,请先完成认证");
      }
      return await user.getIdToken();
    }
    
  3. 调用Cloud Run API时,将Token放入请求头:
    async function callCloudRunApi() {
      const idToken = await getIdToken();
      const response = await fetch("<你的Cloud Run服务URL>", {
        method: "GET", // 匹配你的API请求方法(POST/PUT等)
        headers: {
          "Authorization": `Bearer ${idToken}`,
          "Content-Type": "application/json"
        }
        // 按需添加请求体或参数
      });
      return await response.json();
    }
    

四、(可选)后端添加Token校验,强化安全

虽然Cloud Run的IAM会自动验证Token,但你可以在FastAPI后端额外校验Token来源,确保请求来自你的Firebase项目:

  1. 安装依赖库:
    pip install pyjwt cryptography
    
  2. 编写Token验证依赖:
    import jwt
    from fastapi import Depends, HTTPException, Request
    from jwt.exceptions import InvalidTokenError
    from jwt import PyJWKClient
    
    FIREBASE_PROJECT_ID = "<你的Firebase项目ID>"
    
    async def verify_firebase_token(request: Request):
        auth_header = request.headers.get("Authorization")
        if not auth_header or not auth_header.startswith("Bearer "):
            raise HTTPException(status_code=401, detail="缺少有效身份凭证")
        
        token = auth_header.split(" ")[1]
        try:
            jwks_client = PyJWKClient("https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com")
            signing_key = jwks_client.get_signing_key_from_jwt(token)
            
            payload = jwt.decode(
                token,
                signing_key.key,
                algorithms=["RS256"],
                audience=FIREBASE_PROJECT_ID,
                issuer=f"https://securetoken.google.com/{FIREBASE_PROJECT_ID}"
            )
            return payload
        except InvalidTokenError:
            raise HTTPException(status_code=401, detail="无效的身份凭证")
    
    # 在路由中使用该依赖
    @app.get("/your-api-endpoint")
    async def protected_endpoint(payload: dict = Depends(verify_firebase_token)):
        return {"message": "请求合法", "user_id": payload["user_id"]}
    

五、(可选)用Firebase Hosting重写规则隐藏Cloud Run URL

在firebase.json中配置重写,让前端调用Firebase Hosting路径即可转发到Cloud Run,进一步隐藏后端地址:

{
  "hosting": {
    "public": "build",
    "rewrites": [
      {
        "source": "/api/**",
        "run": {
          "serviceId": "<你的Cloud Run服务ID>",
          "region": "<你的Cloud Run部署区域>"
        }
      }
    ]
  }
}

配置完成后,前端只需调用/api/xxx路径,Firebase Hosting会自动完成请求转发并保留权限验证逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 18:57:38