This repository was archived by the owner on Feb 7, 2022. It is now read-only.
forked from pbojinov/request-ip
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
131 lines (112 loc) · 4.09 KB
/
index.js
File metadata and controls
131 lines (112 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
* Author: petar bojinov - @pbojinov
* Date: 01/27/16
*/
'use strict';
/**
* Get client IP address
*
* Will return 127.0.0.1 when testing locally
* Useful when you need the user ip for geolocation or serving localized content
*
* @method getClientIp
* @param req
* @returns {string} ip
*/
function getClientIp(req, startLevel) {
// the ipAddress we return
var ipAddress;
// workaround to get real client IP
// most likely because our app will be behind a [reverse] proxy or load balancer
var clientIp = req.headers['x-client-ip'];
var forwardedForAlt = req.headers['x-forwarded-for'];
var realIp = req.headers['x-real-ip'];
// more obsure ones below
var clusterClientIp = req.headers['x-cluster-client-ip'];
var forwardedAlt = req.headers['x-forwarded'];
var forwardedFor = req.headers['forwarded-for'];
var forwarded = req.headers['forwarded'];
// remote address check
var reqConnectionRemoteAddress = req.connection ? req.connection.remoteAddress : null;
var reqSocketRemoteAddress = req.socket ? req.socket.remoteAddress : null;
var reqConnectionSocketRemoteAddress = (req.connection && req.connection.socket) ? req.connection.socket.remoteAddress : null;
var reqInfoRemoteAddress = req.info ? req.info.remoteAddress : null;
// x-client-ip
if (clientIp && startLevel <= 1) {
ipAddress = clientIp;
}
// x-forwarded-for
// (typically when your node app is behind a load-balancer (eg. AWS ELB) or proxy)
else if (forwardedForAlt && startLevel <= 2) {
// x-forwarded-for may return multiple IP addresses in the format:
// "client IP, proxy 1 IP, proxy 2 IP"
// Therefore, the right-most IP address is the IP address of the most recent proxy
// and the left-most IP address is the IP address of the originating client.
// source: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/x-forwarded-headers.html
var forwardedIps = forwardedForAlt.split(',');
ipAddress = forwardedIps[0];
}
// x-real-ip
// (default nginx proxy/fcgi)
else if (realIp && startLevel <= 3) {
// alternative to x-forwarded-for, used by some proxies
ipAddress = realIp;
}
// x-cluster-client-ip
// (Rackspace LB and Riverbed's Stingray)
// http://www.rackspace.com/knowledge_center/article/controlling-access-to-linux-cloud-sites-based-on-the-client-ip-address
// https://splash.riverbed.com/docs/DOC-1926
else if (clusterClientIp && startLevel <= 4) {
ipAddress = clusterClientIp;
}
// x-forwarded
else if (forwardedAlt && startLevel <= 5) {
ipAddress = forwardedAlt;
}
// forwarded-for
else if (forwardedFor && startLevel <= 5) {
ipAddress = forwardedFor;
}
// forwarded
else if (forwarded && startLevel <= 5) {
ipAddress = forwarded;
}
// remote address checks
else if (reqConnectionRemoteAddress && startLevel <= 6) {
ipAddress = reqConnectionRemoteAddress;
}
else if (reqSocketRemoteAddress && startLevel <= 7) {
ipAddress = reqSocketRemoteAddress
}
else if (reqConnectionSocketRemoteAddress && startLevel <= 8) {
ipAddress = reqConnectionSocketRemoteAddress
}
else if (reqInfoRemoteAddress && startLevel <= 9) {
ipAddress = reqInfoRemoteAddress
}
// return null if we cannot find an address
else {
ipAddress = null;
}
console.log(ipAddress);
return ipAddress;
}
/**
* Expose mode public functions
*/
exports.getClientIp = getClientIp;
/**
* Expose a default implemtation for a connect middleware
*
* @options.attributeName - name of attribute to augment request object with
* @options.initialLevel - number of the level to start checking (based on how it works section of the documentation)
*/
exports.mw = function (options) {
if (!options) options = {};
var attr = options.attributeName || "clientIp";
var startLevel = options.startLevel || 1;
return function (req, res, next) {
req[attr] = getClientIp(req, startLevel);
next();
}
};