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

GCP Cloud Run中Nginx反向代理跨服务转发的IAM鉴权问题

问题原因与修复方案

核心错误点

你遇到的问题由配置错误叠加Cloud Run IAM鉴权特性共同导致:

  1. Host头配置非法:HTTP规范中Host头只允许填写域名:端口格式,不能带https://协议前缀,你之前配置的https://my-cloud-run-backend.run.app是无效值,后端服务收到后直接返回400错误。
  2. 路径重写规则冲突:你同时配置了带尾斜杠的proxy_pass和自定义rewrite规则,两者都会修改转发路径,容易出现路径拼接异常,甚至导致请求匹配不到正确的location块,落到前端静态资源规则上。
  3. 无效配置冗余:根路径location /用于提供静态文件服务,没有配置反向代理,你在这个块里写的所有proxy_set_header相关配置都不会生效,反而可能干扰Nginx的location匹配逻辑。
  4. IAM令牌受众校验不匹配:受IAM保护的Cloud Run服务会校验请求头中OIDC令牌的aud(受众)字段,必须匹配当前服务的URL才会放行。如果你透传的用户令牌是仅申请给前端服务使用的,后端服务校验时会直接判定令牌无效返回401。

修复步骤

1. 前置权限配置

先给前端Cloud Run的运行时服务账号授予后端服务的roles/run.invoker(Cloud Run调用者)权限,保证前端服务本身有权限访问后端。

2. 替换为正确的Nginx配置

把你的配置文件替换为以下内容,已经移除错误配置、修正头信息、处理了路径匹配问题:

server {
  access_log /dev/stdout;
  listen 8080;

  # 根路径提供前端静态资源,移除无用的proxy配置
  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
    try_files $uri $uri/ /index.html;
  }

  # 处理无尾斜杠的/api路径,避免匹配到根路径规则
  location = /api {
    return 301 /api/;
  }

  location /api/ {
    # proxy_pass末尾带斜杠,会自动剥离/api/前缀,不需要额外rewrite
    proxy_pass https://my-cloud-run-backend.run.app/;

    # 需要透传终端用户身份就保留这行,否则替换为服务账号生成的令牌
    proxy_set_header Authorization $http_authorization;
    # 修正Host头,只保留域名
    proxy_set_header Host my-cloud-run-backend.run.app;

    # 传递标准代理头
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # HTTPS代理必要配置,防止SNI校验失败
    proxy_ssl_server_name on;
    proxy_ssl_name my-cloud-run-backend.run.app;

    # 可选:使用GCP元数据服务器做DNS解析,走内网访问后端降低延迟
    resolver 169.254.169.254 valid=300s;
    resolver_timeout 5s;
  }

  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }
}

额外说明

如果配置后访问/api路径还是返回后端的401,说明你透传的用户令牌受众不包含后端服务地址,这种场景下不要透传用户原始令牌:
你可以通过GCP元数据接口http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/identity?audience=https://my-cloud-run-backend.run.app(请求时需要带Metadata-Flavor: Google头)动态获取前端服务账号对应后端受众的ID令牌,放到Authorization头中发给后端即可,这种方式不需要依赖用户令牌,适合后端不需要感知终端用户身份的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 00:57:31