简体   繁体   中英

How can I generate a Set-Cookie integration response header in AWS API Gateway?

I'm currently using Amazon's API Gateway to create a REST API that interacts directly with DynamoDB (using the "AWS Service" integration type - there is NO lambda in-between). Everything works, except that I'd like to return a Set-Cookie header on the first response, for use with subsequent calls to the API.

For simplicity (security is not a concern here), I'd like to use context.requestId as the cookie's value. The problem is that a Set-Cookie header requires more than just the cookie's value; at minimum it also needs a name for the cookie, in the form CookieName=CookieValue , and realistically I'd also like to set other parameters for it, such as an expiration date.

However, it seems there is no way to combine a context variable with some static text in a "header mapping value", as I'd need for the above format: https://docs.aws.amazon.com/apigateway/latest/developerguide/request-response-data-mappings.html#mapping-response-parameters

So my question is: Is there anything I can put into the "header mapping value" box to get this behavior? Something along the lines of 'id='+context.requestId , but valid? I'd also be open to using alternative setup methods, such as the AWS CLI or importing an OpenAPI file.

For reference, this is the API Gateway input box in question: 在此输入图像描述

Simple header mapping

AWS documentation about Response > Header Mappings > Mapping value on page https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-method-settings-execution-console.html

For Mapping value, use one of the following formats:

integration.response.header. header-name where header-name is the name of a single-valued response header from the backend. For example, to return the backend response's Date header as an API method's response's Timestamp header, the Response header column will contain a Timestamp entry, and the associated Mapping value should be set to integration.response.header.Date . ...

So above boils down to what is supported by DynamoDB . And by looking into one of the API examples like GetItem in docs https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html#API_GetItem_ResponseElements

HTTP/1.1 200 OK
x-amzn-RequestId: <RequestId>
x-amz-crc32: <Checksum>
Content-Type: application/x-amz-json-1.0
Content-Length: <PayloadSizeBytes>
Date: <Date>
{ response json excluded for brevity}

So I would probably try using x-amzn-RequestId header value in mapping

integration.response.header.x-amzn-RequestId

It might be possible that other responses will not contain this header but in that case it would be possible to enable request tracing which will end up spitting back X-Amzn-Trace-Id header

What else can be mapped

AWS response param mapping docs mention available syntax for mappings:

+--------------------------------------+------------------------+
| Mapped Data Source                   | Mapping expression     |
+--------------------------------------+------------------------+
| Integration response header          | integration.response.header.PARAM_NAME |
| Integration response header          | integration.response.multivalueheader.PARAM_NAME |
| Integration response body            | integration.response.body |
| Integration response body (JsonPath) | integration.response.body.JSONPath_EXPRESSION |
| Stage variable                       | stageVariables.VARIABLE_NAME |
| Context variable                     | context.VARIABLE_NAME that must be one of the supported context variables. |
| Static value                         | 'STATIC_VALUE'. The STATIC_VALUE is a string literal and must be enclosed within a pair of single quotes. |
+--------------------------------------+------------------------+

We also know that PARAM_NAME needs to match regular expression ^[a-zA-Z0-9._$-]+$ from that same documentation page.

There are no examples showing concatenation though so even if 'id='+context.requestId syntax is supported there is nothing that prevents it from being removed in the future.

Another alternative - Mapping templates

API Gateway uses Velocity Template Language (VTL) engine to process body mapping templates for the integration request and integration response. The mapping templates translate method request payloads to the corresponding integration request payloads and translate integration response bodies to the method response bodies.

There is a guide on AWS - Use a Mapping Template to Override an API's Request and Response Parameters and Status Codes

Template could look similar to below. I haven't tested it though:

#set($cookieName = "id")
#set($cookieNameValSeparator = "=")
$input.json("$")
#set($context.responseOverride.header.Set-Cookie = "$cookieName$cookieNameValSeparator$context.requestId")

If you'd be interested in using AWS CloudFront that would make this quite simple. In CloudFront you are able to add your own custom headers with name and value, as requests are being routed optimally for your site:

AWS CloudFront Origin Editing

Hope this helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM