diff --git a/README.md b/README.md index aeb3720..0d0cf12 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ feedback/ ├─ thread.php 问题详情 + 回复(含"官方答复"与状态管理、附件展示) ├─ new.php 发布新问题(含图片 / 视频上传) ├─ admin.php 管理后台(口令登录:审核 / 管理全部问题 / 站点设置 / 操作日志) +├─ install.php 安装向导(数据库不存在时自动引导进来;装完建议删除) ├─ upload.php 附件上传接口(两步:领对象键 → 收文件本体,local 落盘 / OSS 代理 PUT) ├─ media.php 附件代理输出(私有桶 + 内网 Endpoint 下图片/视频的唯一对外读取通道,带鉴权与 Range) ├─ captcha.php "换一题"用的人机验证刷新接口(返回 JSON) @@ -60,8 +61,9 @@ feedback/ chown -R www:www /www/wwwroot/你的域名/feedback chmod -R 755 /www/wwwroot/你的域名/feedback/data ``` -4. 首次访问 `https://你的域名/feedback/` 会自动建库建表。 -5. **打开 `config.php`,修改这三项**(务必!): +4. 首次访问 `https://你的域名/feedback/` —— 此时 `data/` 下还没有数据库, + 程序会**自动把你送到安装向导 `install.php`**(见 **第二节之二**)。按向导填完即装好。 +5. 若你更愿意手工配置:从 `config.example.php` 复制一份为 `config.php`,改掉这三项后刷新页面即可建库。 - `admin_password` —— 管理员口令(回复时填入即以「官方」身份答复;也是审核后台 `admin.php` 的登录口令) - `api_token` —— 读取接口的令牌(自己设一串随机字符) - `ip_salt` —— 随机字符串(用于给访客 IP 做哈希) @@ -76,11 +78,50 @@ feedback/ --- +## 二之二、安装向导(`install.php`) + +**什么时候出现**:只要 `data/` 下还没有数据库文件,访问站点的任何页面都会 302 到 `install.php`。 +反过来,数据库一旦存在,向导就只显示「已经装好了」,**不会**覆盖任何数据。 + +向导分三步,一屏走完: + +1. **环境体检** —— PHP 版本(≥7.4)、必需扩展(`pdo_sqlite` / `openssl`)、 + `站点根 / data / uploads` 目录可写性、`config.example.php` 是否在。有任一项不过就拒绝提交。 +2. **填写站点信息** —— 站点标题、站点描述、官方邮箱、站点根地址(后两项可留空)。 +3. **设置管理员口令** —— 至少 8 位;也可以留空、装完后在后台补设(**补设之前后台登不进去**)。 + +提交后向导会: + +- 生成 `config.php`(在 `config.example.php` 的**文本**上逐项替换,注释与 OSS / SMTP 段落原样保留); +- 自动填好 `api_token` 与 `ip_salt`(随机串,不用你操心); +- 建库建表; +- 把口令以 **bcrypt 哈希**写入数据库 `settings` 表 —— **明文不进 `config.php`、不进任何文件**。 + +**装完请做两件事**: + +1. **删掉 `install.php`**(已安装态下它会拒绝重装,但少一个入口少一分风险)。 +2. 若口令留空了,进后台「站点设置 → 登录口令」补设一个。 + +> 想重装(例如换了数据库位置):先手工移走 `data/feedback.db`,再刷新即可。 +> 向导**不会**替你删除任何数据。 + +--- + ## 三、首页加链接 已在官网 `index.html` 的**顶部导航**与**页脚「产品」列**加入「问题反馈」入口,指向 `feedback/`。 (本地文件:`(你的站点首页)`) +### 页脚里有「管理后台」入口 + +站点页脚固定显示一个「管理后台」链接(指向 `admin.php`),不需要手动在地址栏敲文件名。 +旁边那句「由 FeedLite 驱动」可以关掉: + +- 后台「**站点设置 → 页脚**」→ 取消勾选「在页脚显示『由 FeedLite 驱动』」 + → 页脚只剩「管理后台」链接; +- 同一处还能改「FeedLite」二字指向的地址(默认是本项目开源仓库)。 + 只接受 `http://` / `https://` 开头的网址。 + --- ## 四、邮件通知(SMTP) @@ -566,23 +607,42 @@ curl "https://你的域名/feedback/api.php?token=XXX&action=digest&status=open" - `data/` 目录用 `.htaccess` 拒绝一切直接访问;请勿删除该文件。 ### 更换管理员口令 / 令牌 -直接修改 `config.php` 即可,无需改代码。 + +- **管理员口令**:登录后台后在「站点设置 → 登录口令」里改(至少 8 位)。改完即以 bcrypt 哈希存进数据库,`config.php` 里的 `admin_password` 只是「未设置」时的初始值通道。 +- **令牌 `api_token` / 盐 `ip_salt`**:这两项没有后台界面,改 `config.php` 即可,无需改代码。 + +### 口令存在哪、是否加密(重要) + +| 状态 | 存在哪 | 是否加密 | 怎么变成下一档 | +|---|---|---|---| +| 刚 clone 下来、没装 | `config.php` 的 `admin_password` = `CHANGE_ME_admin` | 明文,但**该值已被程序明确禁用**,无法登录 | 跑 `install.php`,或到后台设定口令 | +| 手工在 `config.php` 指定了口令 | `config.php` 的 `admin_password` | **明文**(配置文件里) | 登录一次后到后台改一次口令 → 转为数据库哈希 | +| 正常状态(推荐) | 数据库 `settings` 表的 `admin.password_hash` | **是**,bcrypt 单向哈希(`$2y$…`),不可逆 | 已是最终形态 | + +- 后台「站点设置 → 登录口令」会把当前处于哪一档**如实显示出来**,Linux 下也能直接查库确认。 +- 明文口令**永远不会**由安装向导或后台写进任何文件:向导只把哈希写进数据库。 +- 怀疑口令泄露:到后台改掉即可。若把数据库里 `admin.password_hash` 这一行删掉, + 会退回使用 `config.php` 的值(也因此回到明文档,建议删完立刻重新设定)。 --- ## 七之二、`config.php` 里的三个"必改"参数是什么 -这三项都写在 `config.php` 的「安全」段落里,出厂值都是 `CHANGE_ME_...` 占位符,**上线前必须换成自己的随机值**。 +> **走安装向导的话,这一段可以跳过**:`install.php` 会替你生成 `config.php`, +> 并自动填好 `api_token` 与 `ip_salt`(都是随机串),管理员口令则直接以哈希入库、不进文件。 +> 下面这些是「想手工配置」时看的说明。三项出厂值都是 `CHANGE_ME_...` 占位符。 -### `admin_password` —— 登录口令(初始值) +### `admin_password` —— 登录口令(初始值,可留空) -- **干什么用**:两个地方共用同一串,所以必须一致 —— +- **干什么用**:两个地方共用同一串 —— ① 详情页回复框里填它 → 以「官方」身份发言; ② `/feedback/admin.php` 登录 → 进管理后台(审核、回复、改状态、删帖、改站点设置)。 -- **建议**:**登录后台后在「站点设置 → 修改登录口令」里改成你自己的一串**(至少 8 位)。 +- **建议**:优先用安装向导;若手工配,**登录后台后立刻在「站点设置 → 登录口令」里改成你自己的一串**(至少 8 位)。 改完会以 `password_hash()` 存进数据库,`config.php` 里这行就只是"出厂默认值"了 —— ⚠️ 此时改 `config.php` **不会**再影响登录口令,忘了新口令就去数据库把 `settings` 表里 `admin.password_hash` 这一行删掉,即可退回用 `config.php` 里的值。 +- ⚠️ **占位值 `CHANGE_ME_admin` 已被程序明确禁用**(空值同样):也就是说,**clone 下来不做任何配置时, + 后台任何人都登不进去** —— 这是刻意的,避免"文档里公开的默认口令"变成线上后门。 - **它不是什么**:站点面向访客没有账号体系,也没有访客登录页。它只是一串比对用的口令 —— 表单里填的内容与库里的哈希(或 `config.php` 里的值)比对一次,一致就按官方处理。 diff --git a/admin.php b/admin.php index d7baed8..178cf08 100644 --- a/admin.php +++ b/admin.php @@ -30,6 +30,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['login'])) { $loginErr = '会话已过期,请重试。'; } elseif (!fb_rate_check('admin_login', 10)) { $loginErr = '尝试次数过多,请一小时后再试。'; + } elseif (!fb_admin_password_is_set()) { + $loginErr = '本系统还没有设置登录口令,请先运行安装向导(install.php)完成设置。'; } elseif ($pw !== '' && fb_admin_verify_password($pw)) { fb_admin_login(); fb_mod_log('login'); @@ -46,7 +48,10 @@ if (!fb_admin_logged_in()) {
请输入管理员口令(初始口令在 config.php 的 admin_password,登录后在「站点设置」里可以改掉它)。
请输入管理员口令(当前仍是 config.php 里的 admin_password 明文,登录后请到「站点设置」改成加密存储)。