Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Lete114 committed Dec 10, 2021
0 parents commit f5da57a
Show file tree
Hide file tree
Showing 11 changed files with 1,991 additions and 0 deletions.
18 changes: 18 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# https://editorconfig.org
root = true

[*]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true

[*.md]
max_line_length = 0
trim_trailing_whitespace = false

[COMMIT_EDITMSG]
max_line_length = 0
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# vscode
.vscode

# project file
node_modules

12 changes: 12 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# git
.git

# vscode
.vscode

# project file
node_modules
test
.editorconfig
.prettierrc.yml

9 changes: 9 additions & 0 deletions .prettierrc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# .prettierrc or .prettierrc.yaml
trailingComma: none # 对象或数组最后是否添加逗号 es5|none|all
tabWidth: 2 # 缩进
printWidth: 120 # 多少个字符后换行
semi: false # 结尾处是否添加分号
singleQuote: true # 是否使用单引号
# always:(x) => x
# avoid:x => x
arrowParens: always # 箭头函数在只有一个参数时
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2021 Lete乐特

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
62 changes: 62 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<div align="right">
语言:
中文
<a title="English" href="/README_EN.md">US</a>
</div>

<h1 align="center"><a href="https://github.com/lete114/Get-User-IP" target="_blank">Get-User-IP</a></h1>
<p align="center">一个轻量、小巧的Node.js模块,用于检索请求用户的IP地址</p>

<p align="center">
<a href="https://github.com/Lete114/Get-User-IP/releases/"><img src="https://img.shields.io/npm/v/get-user-ip" alt="Version"></a>
<a href="https://github.com/Lete114/Get-User-IP/tree/main"><img src="https://img.shields.io/github/package-json/v/Lete114/Get-User-IP/main?color=%231ab1ad&label=main" alt="dev"></a>
<a href="https://github.com/Lete114/Get-User-IP/blob/master/LICENSE"><img src="https://img.shields.io/github/license/Lete114/Get-User-IP?color=FF5531" alt="MIT License"></a>
</p>

## 安装

```bash
npm install get-user-ip --save
```

## 快速开始

```javascript
const GetUserIP = require('get-user-ip')
const http = require('http')

const server = http.createServer((req,res)=>{
res.end(GetUserIP(req))
}))

server.listen(6870)

// 如果你使用IPv4,在localhost上你会看到127.0.0.1
// 如果你使用的是IPv6,则为::1, ::fffff:127.0.0.1
```

如果有一些特殊情况的话,例如使用了`CloudFlare`就可以追加第二个参数,它是一个数组所以可以包含多个

```javascript
const server = http.createServer((req,res)=>{
// 这时优先获取 headers.cf-connecting-ip ,如果不存在则继续按默认参数执行
res.end(GetUserIP(req,['headers.cf-connecting-ip']))
}))
```

## 它是如何工作的

它在请求中寻找特定的头信息,如果不存在,则返回`0.0.0.0`默认值

用户 IP 是由以下顺序决定的

```javascript
const defaultHeaders = [
'headers.x-client-ip',
'headers.x-real-ip',
'headers.x-forwarded-for', // 该头信息会返回多个IP,格式为: (客户IP, 代理1 IP,代理2 IP...) 所以返回第一个
'connection.remoteAddress',
'socket.remoteAddress',
'connection.socket.remoteAddress'
]
```
64 changes: 64 additions & 0 deletions README_EN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<div align="right">
Language:
US
<a title="Chinese" href="/README.md">中文</a>
</div>

<h1 align="center"><a href="https://github.com/lete114/Get-User-IP" target="_blank">Get-User-IP</a></h1>
<p align="center">A lightweight, small Node.js module to retrieve the IP address of the requesting user</p>

<p align="center">
<a href="https://github.com/Lete114/Get-User-IP/releases/"><img src="https://img.shields.io/npm/v/get-user-ip" alt="Version"></a>
<a href="https://github.com/Lete114/Get-User-IP/tree/main"><img src="https://img.shields.io/github/package-json/v/Lete114/Get-User-IP/main?color=%231ab1ad&label=main" alt="dev"></a>
<a href="https://github.com/Lete114/Get-User-IP/blob/master/LICENSE"><img src="https://img.shields.io/github/license/Lete114/Get-User-IP?color=FF5531" alt="MIT License"></a>
</p>

## Installation

```bash
npm install get-user-ip --save
```

## Getting Started

```javascript
const GetUserIP = require('get-user-ip')
const http = require('http')

const server = http.createServer((req,res)=>{
res.end(GetUserIP(req))
}))

server.listen(6870)

// on localhost you'll see 127.0.0.1 if you're using IPv4
// or ::1, ::ffff:127.0.0.1 if you're using IPv6
```

If there are some special cases, such as the use of `CloudFlare`, you can append a second parameter, which is an array so it can contain more than one params

```javascript
const server = http.createServer((req,res)=>{
// This gives priority to getting headers.cf-connecting-ip, and if it doesn't exist, continue with the default parameters
res.end(GetUserIP(req,['headers.cf-connecting-ip']))
}))
```

## How It Works

It looks for a specific header in the request and returns the `0.0.0.0` default if it does not exist

The user IP is determined by the following order

```javascript
const defaultHeaders = [
'headers.x-client-ip',
'headers.x-real-ip',
'headers.x-forwarded-for', // This header will return multiple IP addresses, Format: (Client IP, Proxy 1 IP, Proxy 2 IP...) So return the first
'connection.remoteAddress',
'socket.remoteAddress',
'connection.socket.remoteAddress'
]
```


54 changes: 54 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const defaultHeaders = [
'headers.x-client-ip',
'headers.x-real-ip',
'headers.x-forwarded-for',
'connection.remoteAddress',
'socket.remoteAddress',
'connection.socket.remoteAddress'
]

/**
* Get property values dynamically
* @param {Object} obj Object
* @param {String} str Get object string
* @returns {String} Object property values
*/
function GetProperty(obj, str) {
try {
str = str.replace(/\[(\w+)\]/g, '.$1') // Handles array subscripts
let arr = str.split('.')
for (const i in arr) {
obj = obj[arr[i]] || ''
}
return obj
} catch (e) {}
return null
}

/**
* Obtain real IP address of the client
* @param {Object} req Request Object
* @param {Array} headers [Options] Custom Obtain Request Object Headers Info
* @returns {String} IP - If not, it is returned by default '0.0.0.0'
*/
function GetClientIP(req, headers = []) {
if (!req) throw new Error('Request Object Should Not Be Null Or Undefined')

const connectionSocket = req.connection && req.connection.socket
const condition = req.headers || req.connection || connectionSocket || req.socket

if (condition || headers.length) {
headers = [...headers, ...defaultHeaders]

for (const header of headers) {
const ip = GetProperty(req, header)
if (ip) {
return ip.split(',')[0].trim()
}
}
}

return '0.0.0.0'
}

module.exports = GetClientIP
Loading

0 comments on commit f5da57a

Please sign in to comment.