From 13e6f941eb6a1894c6b97e766df224d0c45015b0 Mon Sep 17 00:00:00 2001 From: Lete Date: Wed, 23 Nov 2022 11:01:36 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=A4=B4IP=20(#486)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add custom request header to get IP * Add custom request header to get IP * Add dependencies "get-user-ip" * Add dependencies "get-user-ip" * Add environment variable description * fix(eslint): "getIp" space-before-function-paren * fix(eslint): "getIp" space-before-function-paren --- src/server/self-hosted/README.md | 1 + src/server/self-hosted/index.js | 10 +++++++++- src/server/self-hosted/package.json | 1 + src/server/vercel/api/index.js | 20 ++++++++++++++++---- src/server/vercel/package.json | 1 + 5 files changed, 28 insertions(+), 5 deletions(-) diff --git a/src/server/self-hosted/README.md b/src/server/self-hosted/README.md index 6e872e417..8915b3f7c 100644 --- a/src/server/self-hosted/README.md +++ b/src/server/self-hosted/README.md @@ -20,3 +20,4 @@ tkserver | `TWIKOO_PORT` | 端口号 | `8080` | | `TWIKOO_THROTTLE` | IP 请求限流,当同一 IP 短时间内请求次数超过阈值将对该 IP 返回错误 | `250` | | `TWIKOO_LOCALHOST_ONLY` | 为`true`时只监听本地请求,使得 nginx 等服务器反代之后不暴露原始端口 | `null` | +| `TWIKOO_IP_HEADERS` | 在一些特殊情况下使用,如使用了`CloudFlare CDN` 它会将请求 IP 写到请求头的 `cf-connecting-ip` 字段上,为了能够正确的获取请求 IP 你可以写成 `['headers.cf-connecting-ip']` | `[]` | diff --git a/src/server/self-hosted/index.js b/src/server/self-hosted/index.js index be2c05a84..6b8d641d0 100644 --- a/src/server/self-hosted/index.js +++ b/src/server/self-hosted/index.js @@ -8,6 +8,7 @@ const { version: VERSION } = require('./package.json') const fs = require('fs') const path = require('path') const Loki = require('lokijs') +const getUserIP = require('get-user-ip') const Lfsa = require('lokijs/src/loki-fs-structured-adapter') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { @@ -894,7 +895,14 @@ async function createCollections () { } function getIp (request) { - return request.headers['x-forwarded-for'] || request.socket.remoteAddress || '' + try { + const { TWIKOO_IP_HEADERS } = process.env + const headers = TWIKOO_IP_HEADERS ? JSON.parse(TWIKOO_IP_HEADERS) : [] + return getUserIP(request, headers) + } catch (e) { + console.error('获取 IP 错误信息:', e) + } + return getUserIP(request) } function clearRequestTimes () { diff --git a/src/server/self-hosted/package.json b/src/server/self-hosted/package.json index 429dbdeae..08ae62dd7 100644 --- a/src/server/self-hosted/package.json +++ b/src/server/self-hosted/package.json @@ -24,6 +24,7 @@ "registry": "https://registry.npmjs.org/" }, "dependencies": { + "get-user-ip": "^1.0.1", "lokijs": "^1.5.12", "twikoo-func": "1.6.7", "uuid": "^8.3.2" diff --git a/src/server/vercel/api/index.js b/src/server/vercel/api/index.js index 02ba17512..6afaf258f 100644 --- a/src/server/vercel/api/index.js +++ b/src/server/vercel/api/index.js @@ -6,6 +6,7 @@ const { version: VERSION } = require('../package.json') const MongoClient = require('mongodb').MongoClient +const getUserIP = require('get-user-ip') const { URL } = require('url') const { v4: uuidv4 } = require('uuid') // 用户 id 生成 const { @@ -59,7 +60,7 @@ const requestTimes = {} module.exports = async (request, response) => { const event = request.body || {} - console.log('请求 IP:', request.headers['x-real-ip']) + console.log('请求 IP:', getIp(request)) console.log('请求函数:', event.event) console.log('请求参数:', event) let res = {} @@ -624,7 +625,7 @@ async function parse (comment, request) { mailMd5: comment.mail ? md5(comment.mail) : '', link: comment.link ? comment.link : '', ua: comment.ua, - ip: request.headers['x-real-ip'], + ip: getIp(request), master: isBloggerMail, url: comment.url, href: comment.href, @@ -652,7 +653,7 @@ async function limitFilter (request) { const count = await db .collection('comment') .countDocuments({ - ip: request.headers['x-real-ip'], + ip: getIp(request), created: { $gt: Date.now() - 600000 } }) if (count > limitPerMinute) { @@ -836,7 +837,7 @@ async function setConfig (event) { function protect (request) { // 防御 - const ip = request.headers['x-real-ip'] + const ip = getIp(request) requestTimes[ip] = (requestTimes[ip] || 0) + 1 if (requestTimes[ip] > MAX_REQUEST_TIMES) { console.log(`${ip} 当前请求次数为 ${requestTimes[ip]},已超过最大请求次数`) @@ -916,3 +917,14 @@ async function createCollections () { } return res } + +function getIp (request) { + try { + const { TWIKOO_IP_HEADERS } = process.env + const headers = TWIKOO_IP_HEADERS ? JSON.parse(TWIKOO_IP_HEADERS) : [] + return getUserIP(request, headers) + } catch (e) { + console.error('获取 IP 错误信息:', e) + } + return getUserIP(request) +} diff --git a/src/server/vercel/package.json b/src/server/vercel/package.json index 2dbf2c276..63834b8a6 100644 --- a/src/server/vercel/package.json +++ b/src/server/vercel/package.json @@ -11,6 +11,7 @@ }, "homepage": "https://twikoo.js.org", "dependencies": { + "get-user-ip": "^1.0.1", "mongodb": "^3.6.3", "twikoo-func": "1.6.7", "uuid": "^8.3.2"