Browse Source

🐞 fix: 每次请求重新生成签名等信息

Pchen0 4 days ago
parent
commit
23e4d10448
1 changed files with 115 additions and 107 deletions
  1. 115 107
      lib/Lepao/Worker.js

+ 115 - 107
lib/Lepao/Worker.js

@@ -409,8 +409,13 @@ class Worker {
         this.logger.error(`[${traceId}] ${msg} ${err.stack || err}`)
         this.logger.error(`[${traceId}] ${msg} ${err.stack || err}`)
     }
     }
 
 
-    async request(traceId, name, url, raw, headers = {}, ctx = null) {
+    /**
+     * 学校接口请求:内层 retry 每次重新生成 raw 并签名,避免重试复用同一 timestamp/nonce/sign 触发「非法请求2」。
+     * @param {() => object | object} getRaw 返回请求明文对象的函数,或为兼容旧代码传入 plain object
+     */
+    async request(traceId, name, url, getRaw, headers = {}, ctx = null) {
         return this.retry(async () => {
         return this.retry(async () => {
+            const raw = typeof getRaw === 'function' ? getRaw() : getRaw
             this.log(traceId, 'REQ', name, raw)
             this.log(traceId, 'REQ', name, raw)
 
 
             const mergedHeaders = {
             const mergedHeaders = {
@@ -1148,28 +1153,29 @@ class Worker {
 
 
         /* ---------------- 获取跑步记录 ---------------- */
         /* ---------------- 获取跑步记录 ---------------- */
         this.register('lepao.getRecord', async (req, ctx) => {
         this.register('lepao.getRecord', async (req, ctx) => {
-            const now = this.lepaoTimestamp()
-            const raw = {
-                uid: req.uid,
-                token: req.token,
-                school_id: req.school_id,
-                term_id: 0,
-                course_id: 0,
-                class_id: 0,
-                student_num: req.student_id,
-                card_id: req.student_id,
-                timestamp: now,
-                version: 1,
-                nonce: String(Math.floor(Math.random() * 900000 + 100000)),
-                ostype: 5
-            }
-            raw.sign = dataSign(raw)
-
             return this.request(
             return this.request(
                 ctx.traceId,
                 ctx.traceId,
                 'getRecord',
                 'getRecord',
                 this.api('/Run2/beforeRunV260'),
                 this.api('/Run2/beforeRunV260'),
-                raw,
+                () => {
+                    const now = this.lepaoTimestamp()
+                    const raw = {
+                        uid: req.uid,
+                        token: req.token,
+                        school_id: req.school_id,
+                        term_id: 0,
+                        course_id: 0,
+                        class_id: 0,
+                        student_num: req.student_id,
+                        card_id: req.student_id,
+                        timestamp: now,
+                        version: 1,
+                        nonce: String(Math.floor(Math.random() * 900000 + 100000)),
+                        ostype: 5
+                    }
+                    raw.sign = dataSign(raw)
+                    return raw
+                },
                 {
                 {
                     'User-Agent': req.userAgent,
                     'User-Agent': req.userAgent,
                     'charset': 'utf-8',
                     'charset': 'utf-8',
@@ -1193,28 +1199,29 @@ class Worker {
             const runZoneId = runZoneMap[pathData.run_zone_name]
             const runZoneId = runZoneMap[pathData.run_zone_name]
             if (!runZoneId) throw new Error('跑区不存在')
             if (!runZoneId) throw new Error('跑区不存在')
 
 
-            const raw = {
-                uid: req.uid,
-                token: req.token,
-                school_id: req.school_id,
-                term_id: 0,
-                course_id: 0,
-                class_id: 0,
-                student_num: req.student_id,
-                card_id: req.student_id,
-                timestamp: this.lepaoTimestamp(),
-                version: 1,
-                nonce: String(Math.floor(Math.random() * 900000 + 100000)),
-                ostype: 5,
-                run_zone_id: String(runZoneId)
-            }
-            raw.sign = dataSign(raw)
-
             await this.request(
             await this.request(
                 ctx.traceId,
                 ctx.traceId,
                 'setZone',
                 'setZone',
                 this.api('/Run/setRunZone'),
                 this.api('/Run/setRunZone'),
-                raw,
+                () => {
+                    const raw = {
+                        uid: req.uid,
+                        token: req.token,
+                        school_id: req.school_id,
+                        term_id: 0,
+                        course_id: 0,
+                        class_id: 0,
+                        student_num: req.student_id,
+                        card_id: req.student_id,
+                        timestamp: this.lepaoTimestamp(),
+                        version: 1,
+                        nonce: String(Math.floor(Math.random() * 900000 + 100000)),
+                        ostype: 5,
+                        run_zone_id: String(runZoneId)
+                    }
+                    raw.sign = dataSign(raw)
+                    return raw
+                },
                 {},
                 {},
                 ctx
                 ctx
             )
             )
@@ -1223,27 +1230,28 @@ class Worker {
 
 
         /* ---------------- 获取 OSS STS ---------------- */
         /* ---------------- 获取 OSS STS ---------------- */
         this.register('lepao.getOssSts', async (req, ctx) => {
         this.register('lepao.getOssSts', async (req, ctx) => {
-            const raw = {
-                uid: req.uid,
-                token: req.token,
-                school_id: req.school_id,
-                term_id: 0,
-                course_id: 0,
-                class_id: 0,
-                student_num: req.student_id,
-                card_id: req.student_id,
-                timestamp: this.lepaoTimestamp(),
-                version: 1,
-                nonce: String(Math.floor(Math.random() * 900000 + 100000)),
-                ostype: 5
-            }
-            raw.sign = dataSign(raw)
-
             const res = await this.request(
             const res = await this.request(
                 ctx.traceId,
                 ctx.traceId,
                 'getOssSts',
                 'getOssSts',
                 this.api('/WpIndex/getOssSts'),
                 this.api('/WpIndex/getOssSts'),
-                raw,
+                () => {
+                    const raw = {
+                        uid: req.uid,
+                        token: req.token,
+                        school_id: req.school_id,
+                        term_id: 0,
+                        course_id: 0,
+                        class_id: 0,
+                        student_num: req.student_id,
+                        card_id: req.student_id,
+                        timestamp: this.lepaoTimestamp(),
+                        version: 1,
+                        nonce: String(Math.floor(Math.random() * 900000 + 100000)),
+                        ostype: 5
+                    }
+                    raw.sign = dataSign(raw)
+                    return raw
+                },
                 {},
                 {},
                 ctx
                 ctx
             )
             )
@@ -1315,30 +1323,30 @@ class Worker {
             const ossPath = `Public/Upload/file/run_gyroscope/${boundary.slice(-3)}/${formattedToday}/${timestamp}-${Math.floor(Math.random() * 150)}.txt`
             const ossPath = `Public/Upload/file/run_gyroscope/${boundary.slice(-3)}/${formattedToday}/${timestamp}-${Math.floor(Math.random() * 150)}.txt`
             await this.putOssWithFallback(sts, ossPath, Buffer.from(JSON.stringify(gyrData), 'utf-8'))
             await this.putOssWithFallback(sts, ossPath, Buffer.from(JSON.stringify(gyrData), 'utf-8'))
 
 
-            const data = {
-                uid: req.uid,
-                token: req.token,
-                school_id: req.school_id,
-                term_id: 0,
-                course_id: 0,
-                class_id: 0,
-                student_num: req.student_id,
-                card_id: req.student_id,
-                timestamp: this.lepaoTimestamp(),
-                version: 1,
-                nonce: String(Math.floor(Math.random() * 900000 + 100000)),
-                ostype: 5,
-                record_id: record_id,
-                gyroscope_file: ossPath
-            }
-
-            data.sign = dataSign(data)
-
             return this.request(
             return this.request(
                 ctx.traceId,
                 ctx.traceId,
                 'bindData',
                 'bindData',
                 this.api('/Run2/gyroscope'),
                 this.api('/Run2/gyroscope'),
-                data,
+                () => {
+                    const data = {
+                        uid: req.uid,
+                        token: req.token,
+                        school_id: req.school_id,
+                        term_id: 0,
+                        course_id: 0,
+                        class_id: 0,
+                        student_num: req.student_id,
+                        card_id: req.student_id,
+                        timestamp: this.lepaoTimestamp(),
+                        version: 1,
+                        nonce: String(Math.floor(Math.random() * 900000 + 100000)),
+                        ostype: 5,
+                        record_id: record_id,
+                        gyroscope_file: ossPath
+                    }
+                    data.sign = dataSign(data)
+                    return data
+                },
                 {},
                 {},
                 ctx
                 ctx
             )
             )
@@ -1355,43 +1363,43 @@ class Worker {
             let points = req.point_data.map(({ address, jingwei, ...rest }) => rest)
             let points = req.point_data.map(({ address, jingwei, ...rest }) => rest)
             points = JSON.stringify(points)
             points = JSON.stringify(points)
 
 
-            const data = {
-                uid: req.uid,
-                token: req.token,
-                school_id: req.school_id,
-                term_id: 1,
-                course_id: 0,
-                class_id: 0,
-                student_num: req.student_id,
-                card_id: req.student_id,
-                timestamp: this.lepaoTimestamp(),
-                version: 1,
-                nonce: String(Math.floor(Math.random() * 900000 + 100000)),
-                ostype: 5,
-                game_id: String(req.run_zone_id || 0),
-                start_time: req.run_end_time - Number(pathData.time),
-                end_time: req.run_end_time,
-                distance,
-                record_img: "",
-                log_data: points,
-                file_img: "",
-                is_running_area_valid: 1,
-                mobileDeviceId: 1,
-                mobileModel: req.deviceModel,
-                step_info: stepInfo,
-                step_num: stepData.total_steps,
-                used_time: pathData.time,
-                mobileOsVersion: 1,
-                record_file: req.record_file
-            }
-
-            data.sign = dataSign(data)
-
             return this.request(
             return this.request(
                 ctx.traceId,
                 ctx.traceId,
                 'bindData',
                 'bindData',
                 this.api('/Run/stopRunV278'),
                 this.api('/Run/stopRunV278'),
-                data,
+                () => {
+                    const data = {
+                        uid: req.uid,
+                        token: req.token,
+                        school_id: req.school_id,
+                        term_id: 1,
+                        course_id: 0,
+                        class_id: 0,
+                        student_num: req.student_id,
+                        card_id: req.student_id,
+                        timestamp: this.lepaoTimestamp(),
+                        version: 1,
+                        nonce: String(Math.floor(Math.random() * 900000 + 100000)),
+                        ostype: 5,
+                        game_id: String(req.run_zone_id || 0),
+                        start_time: req.run_end_time - Number(pathData.time),
+                        end_time: req.run_end_time,
+                        distance,
+                        record_img: "",
+                        log_data: points,
+                        file_img: "",
+                        is_running_area_valid: 1,
+                        mobileDeviceId: 1,
+                        mobileModel: req.deviceModel,
+                        step_info: stepInfo,
+                        step_num: stepData.total_steps,
+                        used_time: pathData.time,
+                        mobileOsVersion: 1,
+                        record_file: req.record_file
+                    }
+                    data.sign = dataSign(data)
+                    return data
+                },
                 {},
                 {},
                 ctx
                 ctx
             )
             )