How can I retrieve a user's public IP address via Amazon API Gateway + Lambda (node)

node.jsAmazon Web-ServicesAws LambdaAws Api-Gateway

node.js Problem Overview


I'm currently writing a Node.js lambda function, in which I want to log the incoming requester's public IP address. I've been looking through both the API Gateway and Lambda docs all day, but haven't found a solution.

Does the lambda event object include request metadata I can use to extract the user's IP?

node.js Solutions


Solution 1 - node.js

Update for HTTP APIs

Adding @Elijah's comment. The format for HTTP APIs will be

event['requestContext']['http']['sourceIp']

Edit

A better way is actually to check

event['requestContext']['identity']['sourceIp']

You can also get the User-Agent from the same object

event['requestContext']['identity']['userAgent']

See Cesar's comment below. Headers are easily spoofed and the user can set X-Forwarded-For to anything. AFAIK the sourceIp above is retrieved from the TCP connection.

Original answer

As of September 2017, you can create a method in API Gateway with Lambda Proxy integration, this will give you access to

events['headers']['X-Forwarded-For']

Which will look something like 1.1.1.1,214.25.52.1

The first ip 1.1.1.1 is your user's public ip address.

Solution 2 - node.js

Here is a simple demonstration of using API Gateway's $context.identity.sourceIp in a Lambda function.

API Mapping template:

{
    "sourceIP" : "$context.identity.sourceIp"
}

Lambda function:

'use strict';
console.log('Loading function');
exports.handler = (event, context, callback) => {
    console.log('SourceIP =', event.identity.sourceIP);
    callback(null, event.identity.sourceIP);
};

Solution 3 - node.js

In the API Gateway, it's the value

$context.identity.sourceIp

http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html#context-variable-reference

You can pass that through to your Lambda via a mapping template.

Solution 4 - node.js

API gateway should already include remote IP in http header X-Forwarded-For, so you could:

// 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)
}

Solution 5 - node.js

exports.handler = (event, context) => {
    console.log('ip:', event.headers["x-forwarded-for"].split(",")[0].trim());
};

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrdeggesView Question on Stackoverflow
Solution 1 - node.jsJonathanView Answer on Stackoverflow
Solution 2 - node.jsKenneth Rory DunnView Answer on Stackoverflow
Solution 3 - node.jsMike76View Answer on Stackoverflow
Solution 4 - node.jsSynergyChenView Answer on Stackoverflow
Solution 5 - node.jsOded BreinerView Answer on Stackoverflow