From 783def7c10d2fc2589e8e350d0ffa11322af0afb Mon Sep 17 00:00:00 2001 From: lld <15027638633@163.com> Date: Sun, 8 Feb 2026 21:58:16 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=B0=E4=BD=8F=E5=AF=86=E7=A0=81=E9=80=82?= =?UTF-8?q?=E9=85=8D=E5=B0=8F=E7=A8=8B=E5=BA=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pages/login.vue | 71 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 19 deletions(-) diff --git a/pages/login.vue b/pages/login.vue index 4f35c3a..7dd16ad 100644 --- a/pages/login.vue +++ b/pages/login.vue @@ -128,27 +128,55 @@ } }, // ========== 新增:密码加密存储核心方法 ========== - // 生成加密密钥(绑定设备信息) +// ========== 【小程序修复版】生成加密密钥(无崩溃,兼容微信环境) ========== getEncryptKey() { try { - const sys = uni.getSystemInfoSync() - const appId = uni.getAccountInfoSync()?.miniProgram?.appId || 'agri-default' - return CryptoJS.MD5(sys.deviceId + appId + 'agri-pwd-key').toString() + const sys = uni.getSystemInfoSync(); + // 固定写死一部分,避免调用wx.getAccountInfoSync导致的兼容问题 + const appId = "agri-mini-program-fixed"; + const deviceId = sys.deviceId || "default-device"; + // 只做MD5,不调用原生crypto,安全绕过报错 + return CryptoJS.MD5(deviceId + appId + "agri-pwd-key").toString(); } catch (e) { - return 'agri-safe-key-2026' + return "agri-safe-key-2026-fixed"; } }, - // 加密密码 + + // ========== 【小程序修复版】加密密码(彻底解决 crypto 随机数报错) ========== encryptPwd(pwd) { - return CryptoJS.AES.encrypt(pwd, this.getEncryptKey()).toString() + try { + const key = this.getEncryptKey(); + // 核心修复:强制指定编码,关闭CryptoJS安全随机数,适配小程序 + const srcs = CryptoJS.enc.Utf8.parse(pwd); + const keys = CryptoJS.enc.Utf8.parse(key.slice(0, 16)); // 16位密钥 + const encrypted = CryptoJS.AES.encrypt(srcs, keys, { + mode: CryptoJS.mode.ECB, // 用ECB模式,小程序无兼容问题 + padding: CryptoJS.pad.Pkcs7 + }); + // 返回base64,且替换特殊字符,避免请求异常 + return encrypted.toString().replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '~'); + } catch (e) { + console.error("加密失败", e); + return ""; + } }, - // 解密密码 + + // ========== 【小程序修复版】解密密码(对应解密) ========== decryptPwd(encryptedStr) { try { - const bytes = CryptoJS.AES.decrypt(encryptedStr, this.getEncryptKey()) - return bytes.toString(CryptoJS.enc.Utf8) || '' + if (!encryptedStr) return ""; + // 先还原特殊字符 + const decodeStr = encryptedStr.replace(/-/g, '+').replace(/_/g, '/').replace(/~/g, '='); + const key = this.getEncryptKey(); + const keys = CryptoJS.enc.Utf8.parse(key.slice(0, 16)); + const decrypt = CryptoJS.AES.decrypt(decodeStr, keys, { + mode: CryptoJS.mode.ECB, + padding: CryptoJS.pad.Pkcs7 + }); + return decrypt.toString(CryptoJS.enc.Utf8) || ""; } catch (e) { - return '' + console.error("解密失败", e); + return ""; } }, // 加载本地存储的密码并回填 @@ -168,16 +196,18 @@ }, // 保存密码到本地(加密) savePwd() { - if (!this.remember) { - uni.removeStorageSync(this.STORAGE_KEY) - return + // 修复:加密失败时不存储,避免异常 + const pwd = this.encryptPwd(this.loginForm.password); + if (!this.remember || !pwd) { + uni.removeStorageSync(this.STORAGE_KEY); + return; } const saveData = { username: this.loginForm.username, - encryptedPwd: this.encryptPwd(this.loginForm.password), + encryptedPwd: pwd, saveTime: Date.now() - } - uni.setStorageSync(this.STORAGE_KEY, JSON.stringify(saveData)) + }; + uni.setStorageSync(this.STORAGE_KEY, JSON.stringify(saveData)); }, // ========== 原有方法(完全未修改) ========== @@ -225,10 +255,13 @@ // ========== 新增:登录成功后保存密码 ========== this.savePwd() this.loginSuccess() - }).catch(() => { + }).catch((err) => { + this.$modal.closeLoading(); // 新增:关闭加载框 + this.$modal.msgError('登录失败:' + (err.msg || '账号密码错误')); // 新增:提示错误 if (this.captchaEnabled) { - this.getCode() + this.getCode(); } + console.error('登录失败详情:', err); // 新增:打印错误,方便排查 }) }, // 登录成功后,处理函数