|
|
@@ -0,0 +1,160 @@
|
|
|
+# nobleLife 后台登录密码明文传输修复 — 知识库
|
|
|
+
|
|
|
+> 服务器: aliyun (119.23.65.115)
|
|
|
+> 项目路径: `D:\wwwroot\nobleLife\backend\`
|
|
|
+> 框架: ThinkPHP 6
|
|
|
+> 修复日期: 2026-06-29
|
|
|
+> 修复范围: 后台管理登录页 `/admin/login/index`
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 一、问题描述
|
|
|
+
|
|
|
+后台登录页提交时,用户输入的密码以明文形式出现在浏览器 Network 请求中,存在安全风险。
|
|
|
+
|
|
|
+## 二、修复方案
|
|
|
+
|
|
|
+前后端同时改造:前端提交前对密码做摘要 → 后端只接收校验摘要值,全程不传原文。
|
|
|
+
|
|
|
+### 核心算法
|
|
|
+
|
|
|
+```
|
|
|
+sha1( sha1('blog_') + md5(明文密码) + md5('_encrypt') + sha1(明文密码) )
|
|
|
+```
|
|
|
+
|
|
|
+输出为 40 位 hex 字符串(SHA1 标准长度)。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 三、修改文件清单
|
|
|
+
|
|
|
+| 文件 | 操作 | 修改时间 | 说明 |
|
|
|
+|------|------|----------|------|
|
|
|
+| `public/static/js/login-crypto.js` | 新增 | 06-29 16:33 | 前端密码摘要库 |
|
|
|
+| `app/admin/view/login/index.html` | 修改 | 06-29 16:36 | 登录页引入 crypto、改写提交逻辑 |
|
|
|
+| `app/admin/controller/Login.php` | 修改 | 06-29 16:37 | 后端接收 password_hash |
|
|
|
+| `app/admin/model/AuthUser.php` | 未改 | — | 原逻辑直接兼容 |
|
|
|
+| `app/admin/common.php` | 未改 | — | 原 `password()` 函数算法一致 |
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 四、逐文件变更详情
|
|
|
+
|
|
|
+### 4.1 `public/static/js/login-crypto.js`(新增)
|
|
|
+
|
|
|
+纯 JS 实现的 MD5 + SHA1 库,最终导出函数:
|
|
|
+
|
|
|
+```javascript
|
|
|
+window.adminLoginPasswordHash = function (value) {
|
|
|
+ value = String(value || '');
|
|
|
+ return sha1(sha1('blog_') + md5(value) + md5('_encrypt') + sha1(value));
|
|
|
+};
|
|
|
+```
|
|
|
+
|
|
|
+不依赖任何第三方库,浏览器原生可用。
|
|
|
+
|
|
|
+### 4.2 `app/admin/view/login/index.html`(修改)
|
|
|
+
|
|
|
+**变更前:**
|
|
|
+```javascript
|
|
|
+// 直接提交 data.field(含明文 password)
|
|
|
+$.ajax({
|
|
|
+ url: "{:url('login/loginHandle')}",
|
|
|
+ method: 'post',
|
|
|
+ data: data.field,
|
|
|
+ ...
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+**变更后:**
|
|
|
+```javascript
|
|
|
+var postData = $.extend({}, data.field);
|
|
|
+postData.password_hash = adminLoginPasswordHash(postData.password);
|
|
|
+delete postData.password; // ← 删除明文
|
|
|
+$.ajax({
|
|
|
+ url: "{:url('login/loginHandle')}",
|
|
|
+ method: 'post',
|
|
|
+ data: postData, // ← 只含 password_hash
|
|
|
+ ...
|
|
|
+});
|
|
|
+```
|
|
|
+
|
|
|
+同时 head 中新增引用:
|
|
|
+```html
|
|
|
+<script type="text/javascript" src="__STATIC__/js/login-crypto.js"></script>
|
|
|
+```
|
|
|
+
|
|
|
+### 4.3 `app/admin/controller/Login.php`(修改)
|
|
|
+
|
|
|
+**变更前:**
|
|
|
+```php
|
|
|
+$pwd = trim($data['password'] ?? '');
|
|
|
+```
|
|
|
+
|
|
|
+**变更后:**
|
|
|
+```php
|
|
|
+$pwd = trim($data['password_hash'] ?? '');
|
|
|
+// 新增格式校验:必须为 40 位 hex
|
|
|
+if (!empty($pwd) && !preg_match('/^[a-f0-9]{40}$/i', $pwd)) {
|
|
|
+ return json(['code'=>'400','msg'=>'密码格式错误']);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+### 4.4 `app/admin/model/AuthUser.php`(未改,原逻辑兼容)
|
|
|
+
|
|
|
+```php
|
|
|
+public function getAdminByUsernamePassword($username, $password)
|
|
|
+{
|
|
|
+ $result = Db::name('AuthUser')->where([
|
|
|
+ 'account' => $username,
|
|
|
+ 'password' => $password // 直接对比 DB 中的 hash 值
|
|
|
+ ])->find();
|
|
|
+ return $result ?: false;
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+DB 中 password 字段存储的就是 `password()` 函数的输出哈希,前端传的 hash 与之完全一致,无需改动。
|
|
|
+
|
|
|
+### 4.5 `app/admin/common.php`(未改,算法源头)
|
|
|
+
|
|
|
+```php
|
|
|
+function password($value)
|
|
|
+{
|
|
|
+ $value = sha1('blog_') . md5($value) . md5('_encrypt') . sha1($value);
|
|
|
+ return sha1($value);
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+此函数用于创建/修改管理员时对密码做持久化存储,算法与前端 `adminLoginPasswordHash()` 一致。
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 五、数据流对比
|
|
|
+
|
|
|
+```
|
|
|
+修复前:
|
|
|
+ 用户输入密码 → form submit → Network 可见明文 "123456"
|
|
|
+ 后端: 直接用 password 字段
|
|
|
+
|
|
|
+修复后:
|
|
|
+ 用户输入密码 → JS 本地摘要 → 提交 password_hash → Network 可见 40位hex
|
|
|
+ 后端: 接收 password_hash → 格式校验 → 直接对比 DB hash
|
|
|
+```
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 六、验证方法
|
|
|
+
|
|
|
+1. 打开浏览器 DevTools → Network 标签
|
|
|
+2. 访问后台登录页,输入账号密码点击登录
|
|
|
+3. 查看 loginHandle 请求的 Payload,确认只有 `password_hash` 字段(40位hex),无 `password` 明文
|
|
|
+4. 登录成功后确认正常跳转后台首页
|
|
|
+
|
|
|
+---
|
|
|
+
|
|
|
+## 七、注意事项
|
|
|
+
|
|
|
+1. **不要删除 `app/admin/common.php` 中的 `password()` 函数** — 管理员创建/修改密码仍依赖它存储 hash
|
|
|
+2. **不要删除 `public/static/js/login-crypto.js`** — 前端摘要依赖此文件
|
|
|
+3. **此方案不是 HTTPS 替代** — 摘要传输可防止密码原文泄露,但不能防止重放攻击。生产环境建议同时启用 HTTPS
|
|
|
+4. **API 端登录(`app/api/controller/Login.php`)未同步修改** — 小程序/App 端登录仍走原逻辑,如需修复需单独评估
|