【发布时间】:2016-06-05 00:22:12
【问题描述】:
使用 HTTP 代理集成我想访问 cookie 并将一个添加到 json 响应中。这可能吗?
【问题讨论】:
-
是的,这绝对是可能的。您可以访问所有请求参数(标头、查询字符串、路径、正文),并且可以使用集成请求中的映射模板将它们转换为 HTTP 后端。
标签: amazon-web-services aws-api-gateway
使用 HTTP 代理集成我想访问 cookie 并将一个添加到 json 响应中。这可能吗?
【问题讨论】:
标签: amazon-web-services aws-api-gateway
要在后端访问客户端发送的 cookie,您必须设置从方法请求标头到集成请求标头的映射。
这些说明假设您已经在 API Gateway 中设置了一个简单的方法。
在您的后端访问 cookie
method.request.header.Cookie 的 HTTP 标头。将 cookie 添加到响应中
您可以以类似的方式为方法配置的集成响应/方法响应端设置Set-Cookie 响应标头。
Set-Cookie 的响应标头
Set-Cookie 和映射值integration.response.header.Set-Cookie 的标头映射
请注意,此时 API Gateway 仅支持设置单个 Set-Cookie 响应标头。如果您的后端尝试设置多个 Set-Cookie 标头,则只会设置最后一个。有关详细信息,请参阅此论坛帖子:https://forums.aws.amazon.com/thread.jspa?messageID=701434
【讨论】:
如果您在 API Gateway 方法中选中“使用 Lambda 代理集成”选项,请求标头将通过 event 变量传递给您的 Lambda 函数。 API Gateway 也将期望来自您的回调函数的不同响应。此响应格式可用于指示 Set-Cookie 标头。例如:
callback(null, {
statusCode: 200,
headers: {'Set-Cookie': 'key=val'},
body: 'Some response'
})`
这种方法的优点是不需要任何方法请求或方法响应调整。
这是一个示例 Lambda 函数,它使用此逻辑在每次请求后轮换 cookie 值。
exports.handler = (event, context, callback) => {
var cookies = getCookiesFromHeader(event.headers);
var old_cookie = cookies.flavor;
var new_cookie = pickCookieFlavor(old_cookie);
return callback(null, {
statusCode: 200,
headers: {
'Set-Cookie': setCookieString('flavor', new_cookie),
'Content-Type': 'text/plain'
},
body: 'Your cookie flavor was ' + old_cookie + '. Your new flavor is ' + new_cookie + '.'
});
};
/**
* Rotate the cookie flavor
*/
function pickCookieFlavor(cookie) {
switch (cookie) {
case 'peanut':
return 'chocolate';
case 'chocolate':
return 'raisin and oat';
default:
return 'peanut';
}
}
/**
* Receives an array of headers and extract the value from the cookie header
* @param {String} errors List of errors
* @return {Object}
*/
function getCookiesFromHeader(headers) {
if (headers === null || headers === undefined || headers.Cookie === undefined) {
return {};
}
// Split a cookie string in an array (Originally found http://stackoverflow.com/a/3409200/1427439)
var list = {},
rc = headers.Cookie;
rc && rc.split(';').forEach(function( cookie ) {
var parts = cookie.split('=');
var key = parts.shift().trim()
var value = decodeURI(parts.join('='));
if (key != '') {
list[key] = value
}
});
return list;
};
/**
* Build a string appropriate for a `Set-Cookie` header.
* @param {string} key Key-name for the cookie.
* @param {string} value Value to assign to the cookie.
* @param {object} options Optional parameter that can be use to define additional option for the cookie.
* ```
* {
* secure: boolean // Watever to output the secure flag. Defaults to true.
* httpOnly: boolean // Watever to ouput the HttpOnly flag. Defaults to true.
* domain: string // Domain to which the limit the cookie. Default to not being outputted.
* path: string // Path to which to limit the cookie. Defaults to '/'
* expires: UTC string or Date // When this cookie should expire. Default to not being outputted.
* maxAge: integer // Max age of the cookie in seconds. For compatibility with IE, this will be converted to a
* `expires` flag. If both the expires and maxAge flags are set, maxAge will be ignores. Default to not being
* outputted.
* }
* ```
* @return string
*/
function setCookieString(key, value, options) {
var defaults = {
secure: true,
httpOnly: true,
domain: false,
path: '/',
expires: false,
maxAge: false
}
if (typeof options == 'object') {
options = Object.assign({}, defaults, options);
} else {
options = defaults;
}
var cookie = key + '=' + value;
if (options.domain) {
cookie = cookie + '; domain=' + options.domain;
}
if (options.path) {
cookie = cookie + '; path=' + options.path;
}
if (!options.expires && options.maxAge) {
options.expires = new Date(new Date().getTime() + parseInt(options.maxAge) * 1000); // JS operate in Milli-seconds
}
if (typeof options.expires == "object" && typeof options.expires.toUTCString) {
options.expires = options.expires.toUTCString();
}
if (options.expires) {
cookie = cookie + '; expires=' + options.expires.toString();
}
if (options.secure) {
cookie = cookie + '; Secure';
}
if (options.httpOnly) {
cookie = cookie + '; HttpOnly';
}
return cookie;
}
【讨论】:
event.Records[0].cf.request.headers.cookie[0].value 中,因此可能需要稍微更改函数才能找到 cookie。