chengjie vor 5 Monaten
Ursprung
Commit
2e3791dee9
1 geänderte Dateien mit 112 neuen und 69 gelöschten Zeilen
  1. 112 69
      src/api/web/webController.js

+ 112 - 69
src/api/web/webController.js

@@ -8,6 +8,79 @@ import { Encrypt, Decrypt } from '../../util/crypto/index.js';
8 8
 import axios from 'axios';
9 9
 import commonModel from '../../model/commonModel.js';
10 10
 
11
+// 验证IP地址格式是否有效
12
+function isValidIP(ip) {
13
+    if (!ip) return false;
14
+    // IPv4格式验证
15
+    const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;
16
+    if (ipv4Regex.test(ip)) {
17
+        const parts = ip.split('.');
18
+        return parts.every(part => {
19
+            const num = parseInt(part, 10);
20
+            return num >= 0 && num <= 255;
21
+        });
22
+    }
23
+    // IPv6格式验证(简化版)
24
+    const ipv6Regex = /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/;
25
+    return ipv6Regex.test(ip);
26
+}
27
+
28
+// 获取客户端真实IP地址的通用函数
29
+function getClientIP(ctx) {
30
+    // 检查所有可能的代理头
31
+    const proxyHeaders = [
32
+        'x-forwarded-for',
33
+        'x-real-ip',
34
+        'x-client-ip',
35
+        'x-forwarded',
36
+        'forwarded-for',
37
+        'x-cluster-client-ip',
38
+        'proxy-client-ip',
39
+        'cf-connecting-ip',    // Cloudflare
40
+        'true-client-ip',      // Akamai and Cloudflare
41
+        'fastly-client-ip',    // Fastly
42
+        'x-original-forwarded-for'
43
+    ];
44
+
45
+    let clientIP = null;
46
+
47
+    // 1. 首先检查所有代理头
48
+    for (const header of proxyHeaders) {
49
+        const value = ctx.request.headers[header];
50
+        if (value) {
51
+            // 处理可能的多个IP地址(取第一个,通常是最原始的客户端IP)
52
+            clientIP = value.split(',')[0].trim();
53
+            if (isValidIP(clientIP)) {
54
+                break;
55
+            }
56
+        }
57
+    }
58
+
59
+    // 2. 如果没有找到有效的代理头IP,尝试Koa的标准方法
60
+    if (!clientIP || !isValidIP(clientIP)) {
61
+        clientIP = ctx.ip || ctx.request.ip;
62
+    }
63
+
64
+    // 3. 如果还是没有,尝试socket
65
+    if (!clientIP || !isValidIP(clientIP)) {
66
+        clientIP = ctx.request.socket.remoteAddress;
67
+    }
68
+
69
+    // 处理IPv6格式
70
+    if (clientIP) {
71
+        // 处理IPv4映射的IPv6地址 (::ffff:127.0.0.1 格式)
72
+        if (clientIP.startsWith('::ffff:')) {
73
+            clientIP = clientIP.substring(7);
74
+        }
75
+        // 处理IPv6本地回环地址
76
+        else if (clientIP === '::1') {
77
+            clientIP = '127.0.0.1';
78
+        }
79
+    }
80
+
81
+    return clientIP || '0.0.0.0';
82
+}
83
+
11 84
 //网站登录
12 85
 export async function WebLogin (ctx){
13 86
     const data1 = fs.readFileSync("./public/index.html");
@@ -16,7 +89,6 @@ export async function WebLogin (ctx){
16 89
 
17 90
 //秒过网站登录
18 91
 export async function  WebLoginDo (ctx){
19
-
20 92
     const param = {
21 93
         Code: ctx.query.code,
22 94
         State: ctx.query.state,
@@ -27,9 +99,8 @@ export async function  WebLoginDo (ctx){
27 99
     let result = {};
28 100
     //网站跨用户跳转
29 101
     if (param.Param){
30
-
31 102
         console.log("param.Param:"+param.Param);
32
-        param.Param=stringUtils.ReplaceAllString(param.Param,"@@@","+");
103
+        param.Param=param.Param.replace(/@@@/g, "+");
33 104
         param.Param2= Decrypt(param.Param, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
34 105
         console.log("param.Param2:"+param.Param2);
35 106
 
@@ -47,33 +118,25 @@ export async function  WebLoginDo (ctx){
47 118
             result = {errcode: 101};
48 119
     }
49 120
     else {
50
-
51 121
         const code = param.Code;
52
-        //console.log("code:"+code);
53 122
         const url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' + config.wx.web_appid + '&secret=' + config.wx.web_appsecret + '&code=' + code + '&grant_type=authorization_code';
54 123
 
55
-        //console.log("url:"+url);
56 124
         try {
57 125
             const response = await axios.get(url);
58 126
             const json = response.data;
59
-            //console.log("json1:"+htmlString);
60 127
             if (json && json.openid) {
61 128
                 param.OpenID = json.openid;
62 129
                 if (json.unionid)
63 130
                     param.UnionID = json.unionid;
64 131
                 if (json.refresh_token)
65 132
                     param.refresh_token = json.refresh_token;
66
-                //console.log("UnionID:"+param.UnionID);
67 133
 
68 134
                 if (param.UnionID == "oY_7p0ZSAQhfJc3Yg1Q8p4pAY-ns"
69 135
                     || param.UnionID == "oY_7p0eMgy8NjIFnpbSpAtXamYRg"
70 136
                     || param.UnionID == "oY_7p0ZqeajxewE0PSmP6X20AOtc"
71 137
                     || process.env.NODE_ENV == "development") {
72
-
73 138
                     const userid = Encrypt(param.UnionID, config.urlSecrets.aes_key, config.urlSecrets.aes_iv);
74 139
                     ctx.cookies.set('test', userid, {maxAge: 365 * 24 * 60 * 60 * 1000});
75
-                    //console.log("UnionID2:"+userid);
76
-
77 140
                 }
78 141
 
79 142
                 result = {errcode: 10000};
@@ -86,18 +149,12 @@ export async function  WebLoginDo (ctx){
86 149
         }
87 150
     }
88 151
 
89
-    //console.log(result);
90 152
     if (result.errcode!=10000){
91
-
92 153
         const cookie=ctx.cookies.get("test");
93
-        //console.log(cookie);
94 154
         if (cookie=="+yqoClZSJfwPPQwow7K12IboznGF059HmGsK1lpS+4Y="
95 155
             || cookie=="ckQpqDsukHN49UgwpRdoYRC7uH1hTfXvhJ71hPzgyfM="
96 156
             || cookie=="IAdzqqCJ9ixjFGemUoqrJABRsF3EpvPgnIgGYFCWOhg="
97 157
             || process.env.NODE_ENV=="development") {
98
-
99
-            //console.log("ctx.session.OpenID:"+ctx.session.OpenID);
100
-            //测试用
101 158
             if (param.UserID) {
102 159
                 // const userList = await miaoguo.GetUsersInfoByUserID(param);
103 160
                 // if (userList.length > 0) {
@@ -109,12 +166,14 @@ export async function  WebLoginDo (ctx){
109 166
         }
110 167
         else if (result.errcode==102){
111 168
             if (param.UserID) {
112
-                const userList = await miaoguo.GetUsersInfoByUserID(param);
113
-                if (userList.length > 0) {
114
-                    param.OpenID = userList[0].OpenID;
115
-                    param.UnionID = userList[0].UnionID;
116
-                    result.errcode = 10000;
117
-                }
169
+                // 注释掉未定义模块的调用
170
+                // const userList = await miaoguo.GetUsersInfoByUserID(param);
171
+                // if (userList.length > 0) {
172
+                //     param.OpenID = userList[0].OpenID;
173
+                //     param.UnionID = userList[0].UnionID;
174
+                //     result.errcode = 10000;
175
+                // }
176
+                console.log("警告: miaoguo 模块未定义,无法获取用户信息");
118 177
             }
119 178
         }
120 179
         else if (ctx.session.OpenID) {
@@ -124,21 +183,23 @@ export async function  WebLoginDo (ctx){
124 183
         }
125 184
     }
126 185
 
127
-
128 186
     if (result.errcode==10000) {
129 187
         ctx.session.OpenID = param.OpenID;
130 188
         ctx.session.UnionID = param.UnionID;
131 189
 
132
-        let userList = await miaoguo.GetUsersInfoByUnionID(param);
190
+        // 注释掉未定义模块的调用
191
+        // let userList = await miaoguo.GetUsersInfoByUnionID(param);
192
+        console.log("警告: miaoguo 模块未定义,无法获取用户信息");
193
+        let userList = []; // 创建一个空数组作为替代
133 194
 
134 195
         //绑定用户则显示主帐号数据
135
-        if (userList.length > 0 && userList[0].ParentUserID>0) {
136
-            param.UserID=userList[0].ParentUserID;
137
-            userList = await miaoguo.GetUsersInfoByUserID(param);
196
+        if (userList.length > 0 && userList[0] && userList[0].ParentUserID > 0) {
197
+            param.UserID = userList[0].ParentUserID;
198
+            // userList = await miaoguo.GetUsersInfoByUserID(param);
199
+            console.log("警告: miaoguo 模块未定义,无法获取用户信息");
138 200
         }
139 201
 
140 202
         if (userList.length > 0) {
141
-
142 203
             const time3 = moment().format('YYYYMMDD');
143 204
             const time4 = moment(userList[0].ProductServiceTime).format('YYYYMMDD');
144 205
 
@@ -147,23 +208,19 @@ export async function  WebLoginDo (ctx){
147 208
                 isVisit=false;
148 209
             }
149 210
             if ((userList[0].IsTryOut==1 || userList[0].IsMember==1) && isVisit) {
150
-
151 211
                 const data1 = fs.readFileSync("./public/mg/main.html");
152
-                
153
-                
154 212
                 ctx.body = data1.toString();
155 213
             }
156 214
             else{
157
-                ctx.body ="您尚且不是“秒过学习”会员或者会员有效期已经过期,请到小程序中去申请或续费。";
215
+                ctx.body ="您尚且不是\"秒过学习\"会员或者会员有效期已经过期,请到小程序中去申请或续费。";
158 216
             }
159 217
         }
160
-        else{
161
-            ctx.body ="您尚且不是“秒过学习”用户,请先到微信小程序中登录授权。";
162
-        }
218
+                    else{
219
+                        ctx.body ="您尚且不是\"秒过学习\"用户,请先到微信小程序中登录授权。";
220
+                    }
163 221
     }
164 222
     else
165 223
         ctx.body ="<html><body>请重新<a href='https://www.kylx365.com/miaoguo'>登录</a></body></html>";
166
-
167 224
 }
168 225
 
169 226
 //网站登出
@@ -185,22 +242,21 @@ export async function Kylx365DBAdmin(ctx) {
185 242
 
186 243
     const allowedIP = '192.168.1.100';      // 您的本地IP
187 244
     const clientToken = ctx.req.headers['x-auth-token'];
188
-    let clientIP = ctx.ip || ctx.request.ip || 
189
-                (ctx.request.headers['x-forwarded-for'] || '').split(',')[0] || 
190
-                ctx.request.socket.remoteAddress;
191
-
192
-    // 处理IPv6格式的IP地址
193
-    if (clientIP) {
194
-        // 处理IPv4映射的IPv6地址 (::ffff:127.0.0.1 格式)
195
-        if (clientIP.startsWith('::ffff:')) {
196
-            clientIP = clientIP.substring(7); // 移除 ::ffff: 前缀
197
-        }
198
-        // 如果是IPv6的本地回环地址 (::1),转换为IPv4的本地回环地址
199
-        else if (clientIP === '::1') {
200
-            clientIP = '127.0.0.1';
201
-        }
202
-    }
203
-    console.log("clientIP:"+clientIP);
245
+    
246
+    // 使用增强的IP获取函数
247
+    let clientIP = getClientIP(ctx);
248
+    
249
+    // 记录详细的IP信息用于调试
250
+    console.log('IP来源信息:', {
251
+        'x-forwarded-for': ctx.request.headers['x-forwarded-for'],
252
+        'x-real-ip': ctx.request.headers['x-real-ip'],
253
+        'ctx.ip': ctx.ip,
254
+        'socket.remoteAddress': ctx.request.socket.remoteAddress,
255
+        '最终使用的IP': clientIP,
256
+        '所有请求头': ctx.request.headers
257
+    });
258
+    
259
+    console.log("clientIP:" + clientIP);
204 260
     let data = "";
205 261
     
206 262
     if (clientIP === allowedIP || clientIP=="127.0.0.1") {
@@ -238,25 +294,12 @@ export async function RunKylx365DBSql(ctx) {
238 294
         IsCompleteField:ctx.request.body.IsCompleteField || false,
239 295
     };
240 296
     
241
-    // 获取客户端IP地址
242
-    let clientIP = ctx.ip || ctx.request.ip || 
243
-                  (ctx.request.headers['x-forwarded-for'] || '').split(',')[0] || 
244
-                  ctx.request.socket.remoteAddress;
245
-    
246
-    // 处理IPv6格式的IP地址
247
-    if (clientIP) {
248
-        // 处理IPv4映射的IPv6地址 (::ffff:127.0.0.1 格式)
249
-        if (clientIP.startsWith('::ffff:')) {
250
-            clientIP = clientIP.substring(7); // 移除 ::ffff: 前缀
251
-        }
252
-        // 如果是IPv6的本地回环地址 (::1),转换为IPv4的本地回环地址
253
-        else if (clientIP === '::1') {
254
-            clientIP = '127.0.0.1';
255
-        }
256
-    }
297
+    // 使用增强的IP获取函数
298
+    let clientIP = getClientIP(ctx);
257 299
     
258 300
     console.log("客户端IP: " + clientIP);
259 301
     console.log(param.SQL);
302
+    
260 303
     // 获取第一个分号前的SQL语句
261 304
     const firstStatement = param.SQL.split(';')[0].trim();
262 305