在 Lambda 中获取用户的 IP 地址(使用 API 网关和 Python) [英] Get user's IP Address in Lambda (with API Gateway, and Python)

查看:111
本文介绍了在 Lambda 中获取用户的 IP 地址(使用 API 网关和 Python)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用这种技术(

向下滚动到底部,如果没有任何模板,请输入application/json";并单击复选框(注意,application/json"是浅灰色字母,但仅单击复选框而不键入它是行不通的).

然后我输入了以下模板:

<代码>{client_ip": "$input.params('X-Forwarded-For')",用户代理": "$input.params('User-Agent')",身体": $input.json('$.body')}

注意:如果我输入 $input.json('$') 或 $input.json('body'),我会得到一个body"我的身体"内的场字段,打破了当前的逻辑.

当网页完成时,它看起来像这样:

下一步是将您的模板重新部署到部署阶段";(环境)你正在使用.

顺便说一下,在进入模板的时候,如果点击Method Request passthrough"在生成模板"中下拉框,它会生成一个这样的模板(我没有使用这个选项,但很快就会阅读更多相关信息):

## 见 http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html## 此模板将通过主体/有效负载将所有参数(包括路径、查询字符串、标头、阶段变量和上下文)传递到集成端点#set($allParams = $input.params()){身体-json": $input.json('$'),参数":{#foreach($type in $allParams.keySet())#set($params = $allParams.get($type))$type":{#foreach($paramName 在 $params.keySet())$paramName": "$util.escapeJavaScript($params.get($paramName))";#if($foreach.hasNext),#end#结尾}#if($foreach.hasNext),#end#结尾},阶段变量":{#foreach($stageVariables.keySet() 中的 $key)$key":$util.escapeJavaScript($stageVariables.get($key))";#if($foreach.hasNext),#end#结尾},上下文":{帐户 ID":$context.identity.accountId",api-id":$context.apiId",api-key":$context.identity.apiKey",authorizer-principal-id":$context.authorizer.principalId",来电者":$context.identity.caller",认知-身份验证-提供者":$context.identity.cognitoAuthenticationProvider",认知认证型":$context.identity.cognitoAuthenticationType",认知身份ID":$context.identity.cognitoIdentityId",认知身份池ID":$context.identity.cognitoIdentityPoolId",http-方法":$context.httpMethod",舞台":$context.stage",源IP":$context.identity.sourceIp",用户":$context.identity.user",用户代理":$context.identity.userAgent",用户-arn":$context.identity.userArn",请求 ID":$context.requestId",资源 ID":$context.resourceId",资源路径":$context.resourcePath"}}

映射模板的两个参考:

  1. https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
  2. https://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html

关于何时使用$input.params",我还有一些研究要做.对比$context.some_value".

I was using this technique (How could I retrieve AWS Lambda public IP address by using Python?) but it gives the IPAddress of the Lambda Server within AWS.

Based on this: How can I retrieve a user's public IP address via Amazon API Gateway + Lambda (node), it looks like I should be able to use

ip_address = event['requestContext']['identity']['sourceIp'];

My handler starts like this:

def lambda_handler(event, context):

but if I do a pprint.pprint(event), I don't see any RequestContext in it, only the "body".

The last comment by FFXSam on the Jonathan answer says "It should be noted that event.requestContext.identity is not present if you're serving a page that's not behind an authorizer.". I'm not sure what that means or why it is true. I'm using API Gateway, and JavaScript code on the client side is calling it.

I could ask the client coder to send me the local IP Address in the body, but it seems like I should be able to get it in the Lambda function itself.

Someone ask for the events, even though I said it only had the fields being passed in a json element called "body":

code:

print("pprint event:")
pprint.pprint(event)


2021-06-06T13:30:01.231-05:00   pprint event:
2021-06-06T13:30:01.231-05:00   {'body': {'ResponseTimeMilliseconds': 2225,
2021-06-06T13:30:01.231-05:00   'authToken': '12312312',
2021-06-06T13:30:01.231-05:00   'handNumber': 7}}

解决方案

I rewarded bounty to Muzaffar Shaikh, but here I will give a more thorough explanation, which seems to be lacking on StackOverflow. His answer got the IP Address, but dropped my "body" field, but it certainly pointed me in the right direction.

In the AWS API Gateway tool, click "Resources" then your method (mine was "Post"), then click on "Integration Request" as shown here.

Scroll down to the bottom, and if there are not any templates, type in "application/json" and click the checkbox (note, "application/json" is there in light gray letters, but just clicking the checkbox without typing it doesn't work).

Then I put in the following template:

{
   "client_ip" : "$input.params('X-Forwarded-For')",
   "user_agent" : "$input.params('User-Agent')",
   "body" : $input.json('$.body') 
}

NOTE: if I put $input.json('$') or $input.json('body'), I ended up with a "body" field inside my "body" field, which broke the current logic.

When the web page was completed, it looked like this:

The next step is to redeploy your template to the "deploy stage" (environment) you were using.

By the way, when entering the template, if you click "Method Request passthrough" in the "Generate template" drop down box, it will generate a template like this (I didn't use this option, but will read more about it soon):

##  See http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
##  This template will pass through all parameters including path, querystring, header, stage variables, and context through to the integration endpoint via the body/payload
#set($allParams = $input.params())
{
"body-json" : $input.json('$'),
"params" : {
#foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
"$type" : {
    #foreach($paramName in $params.keySet())
    "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
        #if($foreach.hasNext),#end
    #end
}
    #if($foreach.hasNext),#end
#end
},
"stage-variables" : {
#foreach($key in $stageVariables.keySet())
"$key" : "$util.escapeJavaScript($stageVariables.get($key))"
    #if($foreach.hasNext),#end
#end
},
"context" : {
    "account-id" : "$context.identity.accountId",
    "api-id" : "$context.apiId",
    "api-key" : "$context.identity.apiKey",
    "authorizer-principal-id" : "$context.authorizer.principalId",
    "caller" : "$context.identity.caller",
    "cognito-authentication-provider" : "$context.identity.cognitoAuthenticationProvider",
    "cognito-authentication-type" : "$context.identity.cognitoAuthenticationType",
    "cognito-identity-id" : "$context.identity.cognitoIdentityId",
    "cognito-identity-pool-id" : "$context.identity.cognitoIdentityPoolId",
    "http-method" : "$context.httpMethod",
    "stage" : "$context.stage",
    "source-ip" : "$context.identity.sourceIp",
    "user" : "$context.identity.user",
    "user-agent" : "$context.identity.userAgent",
    "user-arn" : "$context.identity.userArn",
    "request-id" : "$context.requestId",
    "resource-id" : "$context.resourceId",
    "resource-path" : "$context.resourcePath"
    }
}

Two reference for mapping templates:

  1. https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
  2. https://docs.aws.amazon.com/apigateway/latest/developerguide/models-mappings.html

I still have some research to do as to when to user "$input.params" vs "$context.some_value".

这篇关于在 Lambda 中获取用户的 IP 地址(使用 API 网关和 Python)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆