Google Cloud API Gateway预检请求API Key认证失败及CORS问题
解决方案
问题根源是API Gateway默认会对所有请求(包括OPTIONS预检请求)强制认证,但预检请求不会携带API Key,导致401错误。以下是针对性的修复步骤:
1. 配置OpenAPI跳过OPTIONS请求的认证
在你的API Gateway OpenAPI配置文件中,为每个需要CORS的路径显式定义OPTIONS方法,并设置security: []跳过认证,同时开启CORS支持:
paths: "/your-api-endpoint": # 处理预检请求的OPTIONS方法 options: x-google-backend: address: "https://your-cloud-run-service.a.run.app" allowCors: true security: [] # 关键:跳过认证,让预检请求通过 responses: '200': description: "Preflight response" headers: Access-Control-Allow-Origin: type: string Access-Control-Allow-Methods: type: string Access-Control-Allow-Headers: type: string # 你的其他业务方法(GET/POST等) get: x-google-backend: address: "https://your-cloud-run-service.a.run.app" security: - api_key: [] responses: '200': description: "Success response"
2. 调整Cloud Run服务端的CORS配置
由于你的请求携带API Key(属于自定义认证头),不能使用*作为允许的源,必须指定React客户端的具体域名。以Express为例:
const express = require('express'); const app = express(); // CORS中间件 app.use((req, res, next) => { // 替换成你的React应用域名,比如https://your-react-app.com res.header('Access-Control-Allow-Origin', 'https://your-react-client-domain'); res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); // 必须包含API Key的请求头(比如你用的x-api-key) res.header('Access-Control-Allow-Headers', 'Content-Type, x-api-key'); // 直接响应OPTIONS请求,不进入业务逻辑 if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); // 你的API路由 app.get('/your-api-endpoint', (req, res) => { res.json({ data: 'Hello World' }); }); app.listen(process.env.PORT || 8080);
3. 配置API Gateway全局CORS策略
在OpenAPI配置的根节点添加全局CORS规则,和服务端配置保持一致:
openapi: 3.0.0 info: title: Your API version: 1.0.0 x-google-endpoints: - name: "your-api-gateway-url.gateway.dev" allowCors: true corsPolicy: allowOrigins: - "https://your-react-client-domain" # 对应服务端的源 allowMethods: - "GET" - "POST" - "OPTIONS" allowHeaders: - "x-api-key" - "Content-Type"
常见避坑点
- 不要在OPTIONS方法的配置中添加任何认证规则,
security: []是必填项 - 携带认证头的请求,
Access-Control-Allow-Origin必须是具体域名,不能用*,否则浏览器会拒绝响应 - 确保Cloud Run服务没有额外拦截OPTIONS请求,必须直接返回200状态码
内容的提问来源于stack exchange,提问作者DeeJay
相关产品推荐
相关产品推荐

