如何在AWS API Gateway中硬编码X-IS-MOBILE请求头?
问题
我们有一个API Gateway,移动应用的请求需通过它代理后才能到达核心API,Web应用则直接访问核心API。我们希望区分来自移动应用的请求,但不想修改并重新提交移动应用,因此想在API Gateway中硬编码请求头"X-IS-MOBILE": "true"。
我首先尝试在parameters中添加该请求头:
swagger: "2.0" info: version: "2019-07-22T10:33:53Z" title: "Mobile API Integration" host: "mobile.domain.link" basePath: "/v3" schemes: - "https" paths: /app-info: post: operationId: "appInfo" consumes: - "application/json" produces: - "application/json" parameters: - in: header name: "X-IS-MOBILE" type: boolean default: true - in: "body" name: "AppInfoPayload" required: true schema: $ref: "#/definitions/AppInfoPayload" responses: "200": description: "200 response" schema: $ref: "#/definitions/AppInfoView" headers: Access-Control-Allow-Origin: type: "string" Access-Control-Allow-Headers: type: "string" "400": description: "400 response" schema: $ref: "#/definitions/ApiError" "401": description: "401 response" schema: $ref: "#/definitions/ApiError" "500": description: "500 response" schema: $ref: "#/definitions/ApiError" x-amazon-apigateway-integration: httpMethod: "POST" uri: "https://api.domain.link/v1/app-info" responses: default: statusCode: "200" passthroughBehavior: "when_no_match" type: "http_proxy" options: produces: - "application/json" responses: "200": description: "200 response" schema: $ref: "#/definitions/Empty" headers: Access-Control-Allow-Origin: type: "string" Access-Control-Allow-Methods: type: "string" Access-Control-Allow-Headers: type: "string" x-amazon-apigateway-integration: httpMethod: "OPTIONS" uri: "https://api.domain.link/v1/app-info" responses: default: statusCode: "200" passthroughBehavior: "when_no_match" type: "http_proxy"
但这不起作用,查看核心API日志后发现请求头中没有X-IS-MOBILE。
随后我尝试在x-amazon-apigateway-integration中使用requestTemplates:
swagger: "2.0" info: version: "2019-07-22T10:33:53Z" title: "Mobile API Integration" host: "mobile.domain.link" basePath: "/v3" schemes: - "https" paths: /app-info: post: operationId: "appInfo" consumes: - "application/json" produces: - "application/json" parameters: - in: "body" name: "AppInfoPayload" required: true schema: $ref: "#/definitions/AppInfoPayload" responses: "200": description: "200 response" schema: $ref: "#/definitions/AppInfoView" headers: Access-Control-Allow-Origin: type: "string" Access-Control-Allow-Headers: type: "string" "400": description: "400 response" schema: $ref: "#/definitions/ApiError" "401": description: "401 response" schema: $ref: "#/definitions/ApiError" "500": description: "500 response" schema: $ref: "#/definitions/ApiError" x-amazon-apigateway-integration: httpMethod: "POST" uri: "https://api.domain.link/v1/app-info" requestTemplates: 'application/json': | { "headers": { "X-IS-MOBILE": "true" }, "body": $input.json('$') } responses: default: statusCode: "200" passthroughBehavior: "when_no_match" type: "http_proxy" options: produces: - "application/json" responses: "200": description: "200 response" schema: $ref: "#/definitions/Empty" headers: Access-Control-Allow-Origin: type: "string" Access-Control-Allow-Methods: type: "string" Access-Control-Allow-Headers: type: "string" x-amazon-apigateway-integration: httpMethod: "OPTIONS" uri: "https://api.domain.link/v1/app-info" responses: default: statusCode: "200" passthroughBehavior: "when_no_match" type: "http_proxy"
相关代码片段:
requestTemplates: 'application/json': | { "headers": { "X-IS-MOBILE": "true" }, "body": $input.json('$') }
但这仍然不起作用,核心API日志中依旧没有X-IS-MOBILE请求头。请问我哪里操作错了?
解决方案
你的两次尝试都存在问题,核心原因是使用了http_proxy类型的集成,这种模式下API Gateway会直接透传请求,忽略你配置的参数默认值和requestTemplates。
错误原因分析
第一种方法:parameters里加默认值
- Swagger里的
parameters配置只是API Gateway的请求校验规则,默认值不会自动添加到转发给后端的请求头里,尤其是http_proxy模式下,只会透传客户端实际发送的请求头。
- Swagger里的
第二种方法:requestTemplates
requestTemplates只在aws、aws_proxy或者http类型的集成中生效,http_proxy模式下完全不处理模板,直接转发原始请求。
正确做法
把集成类型从http_proxy改成http,然后通过requestParameters来添加请求头,具体配置如下:
x-amazon-apigateway-integration: httpMethod: "POST" uri: "https://api.domain.link/v1/app-info" requestParameters: integration.request.header.X-IS-MOBILE: "'true'" responses: default: statusCode: "200" passthroughBehavior: "when_no_match" type: "http"
关键说明
- 集成类型改为
http:这种模式允许你修改请求头、请求体等内容,而http_proxy是纯透传。 - 使用
requestParameters:通过integration.request.header.HEADER_NAME的格式来设置硬编码的请求头值,注意字符串值需要用单引号包裹(比如'true'),如果是布尔值可以直接写true。 - 保留原有请求头:如果需要透传客户端发送的其他请求头,需要在
requestParameters里显式声明,比如:integration.request.header.Authorization: "method.request.header.Authorization"
完整的POST接口配置示例
paths: /app-info: post: operationId: "appInfo" consumes: - "application/json" produces: - "application/json" parameters: - in: "body" name: "AppInfoPayload" required: true schema: $ref: "#/definitions/AppInfoPayload" responses: "200": description: "200 response" schema: $ref: "#/definitions/AppInfoView" headers: Access-Control-Allow-Origin: type: "string" Access-Control-Allow-Headers: type: "string" "400": description: "400 response" schema: $ref: "#/definitions/ApiError" "401": description: "401 response" schema: $ref: "#/definitions/ApiError" "500": description: "500 response" schema: $ref: "#/definitions/ApiError" x-amazon-apigateway-integration: httpMethod: "POST" uri: "https://api.domain.link/v1/app-info" requestParameters: integration.request.header.X-IS-MOBILE: "'true'" responses: default: statusCode: "200" passthroughBehavior: "when_no_match" type: "http"
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

