【发布时间】:2016-01-08 19:25:03
【问题描述】:
我目前正在编写一个 Node.js lambda 函数,我想在其中记录传入请求者的公共 IP 地址。我整天都在查看 API Gateway 和 Lambda 文档,但没有找到解决方案。
lambda event 对象是否包含可用于提取用户 IP 的请求元数据?
【问题讨论】:
标签: node.js amazon-web-services aws-lambda aws-api-gateway
我目前正在编写一个 Node.js lambda 函数,我想在其中记录传入请求者的公共 IP 地址。我整天都在查看 API Gateway 和 Lambda 文档,但没有找到解决方案。
lambda event 对象是否包含可用于提取用户 IP 的请求元数据?
【问题讨论】:
标签: node.js amazon-web-services aws-lambda aws-api-gateway
在 API 网关中,就是价值
$context.identity.sourceIp
您可以通过映射模板将其传递给您的 Lambda。
【讨论】:
$context.multiValueHeaders.x-forwarded-for 而不是 $context.identity.sourceIP - 你也可以在接受的答案上考虑 Roman 的评论。
这是在 Lambda 函数中使用 API Gateway 的 $context.identity.sourceIp 的简单演示。
API 映射模板:
{
"sourceIP" : "$context.identity.sourceIp"
}
Lambda 函数:
'use strict';
console.log('Loading function');
exports.handler = (event, context, callback) => {
console.log('SourceIP =', event.identity.sourceIP);
callback(null, event.identity.sourceIP);
};
【讨论】:
X-Forwarded-For 标头中给出。
HTTP API 更新
添加@Elijah 的评论。 HTTP API 的格式为
event['requestContext']['http']['sourceIp']
编辑
更好的方法实际上是检查
event['requestContext']['identity']['sourceIp']
你也可以从同一个对象中获取 User-Agent
event['requestContext']['identity']['userAgent']
请参阅下面的 Cesar 评论。标头很容易被欺骗,用户可以将X-Forwarded-For 设置为任何内容。 AFAIK 上面的sourceIp 是从 TCP 连接中检索到的。
原答案
自 2017 年 9 月起,您可以在 API 网关中创建一个与 Lambda 代理集成的方法,这将使您能够访问
events['headers']['X-Forwarded-For']
看起来像1.1.1.1,214.25.52.1
第一个 ip 1.1.1.1 是您用户的公共 ip 地址。
【讨论】:
X-Forwarded-For 标头可以被用户欺骗并更改为他们想要的任何内容。
X-Forwarded-For 确实可以由客户端根据请求设置,这使得仅在您拥有受信任的代理并且您的代码只信任最右边的值。见developer.mozilla.org/en-US/docs/Web/HTTP/Headers/…
exports.handler = (event, context) => {
console.log('ip:', event.headers["x-forwarded-for"].split(",")[0].trim());
};
【讨论】:
API 网关应该已经在 http 标头 X-Forwarded-For 中包含远程 IP,因此您可以:
// Lambda handler function
module.exports.handlerFunc = async (event, context) => {
// `X-Forwarded-For` should return a comma-delimited list of IPs, first one being remote IP:
// X-Forwarded-For: '<remote IP>, <cloudfront/API gateway IP>, ...'
const remoteIp = event.headers['X-Forwarded-For'].split(', ')[0]
// If you want to see more info available in event and context, add following, deploy and check CloudWatch log:
// console.log(event, context)
}
【讨论】: