## 管理员账号(用户名 + 口令) 原先只有口令,没有用户名。现在两者都有: - 用户名词入库 settings 的 admin.username(2~32 位,字母数字下划线点连字符) - 口令仍是 bcrypt 哈希存 admin.password_hash,明文不落任何文件 - 登录校验 fb_admin_verify_login():用户名或口令任一不对都返回同一句 「用户名或口令不正确」,且用户名错时也照常跑一次 password_verify,避免用耗时探测账号 - 向后兼容:老部署只设了口令没用户名时,仍可只填口令登录, 并在登录页提示补一个用户名 ## 安装向导精简 按用户要求「没数据就初始化,填完进主页」: - 必填只剩 4 项:网站名称、管理员用户名、口令、确认口令 - 站点描述 / 官方邮箱 / 站点根地址改为 hidden(可留空自动探测) - 密钥、令牌原本就自动生成 - 安装成功后展示网站名称与用户名,2 秒自动跳首页,也有按钮 - 按钮文案改为「完成安装,进入首页」 ## 修掉一个真实 bug 首页把软件说明当成站点描述,导致「软件有 note 时站点描述被顶掉」。 两者是不同的东西:站点描述是全局设置必须始终显示,软件说明另起一行补充。 老基线 D6「首页描述变为新描述」就是被这个 bug 弄失败的。 ## 另一个坑 admin.username 忘了加进 fb_setting_keys() 白名单,fb_set_setting() 会静默丢弃, 表现为「安装时填了用户名,装完却没有」。已补。 验证: - 全新安装流程 32/32(真空站:无 config.php、无 data/*.db) - 老基线 25/25、附件专项 22/22、安装向导 60/60 - PHP 8.5 全部入口 0 弃用
This commit is contained in:
@@ -300,6 +300,7 @@ function fb_setting_keys() {
|
||||
'oss.verify', 'oss.image_process', 'oss.use_internal_endpoint',
|
||||
'moderation.enabled', 'moderation.close_mail_subject',
|
||||
'admin.password_hash',
|
||||
'admin.username',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -452,6 +453,51 @@ function fb_admin_set_password($pw) {
|
||||
return fb_set_setting('admin.password_hash', password_hash((string)$pw, PASSWORD_DEFAULT));
|
||||
}
|
||||
|
||||
/* ---------------- 管理员账号(用户名 + 口令) ----------------
|
||||
* 用户名存数据库(admin.username),口令存 bcrypt 哈希(admin.password_hash)。
|
||||
* 两者缺一不可:用户名不存在时也照常走一次 password_verify,避免用响应快慢探测账号。
|
||||
*/
|
||||
|
||||
/** 管理员用户名;没设过返回空串 */
|
||||
function fb_admin_username() {
|
||||
return trim((string)fb_setting('admin.username', ''));
|
||||
}
|
||||
|
||||
/** 设置管理员用户名 */
|
||||
function fb_admin_set_username($name) {
|
||||
$name = trim((string)$name);
|
||||
if ($name === '') { return false; }
|
||||
return fb_set_setting('admin.username', $name);
|
||||
}
|
||||
|
||||
/** 账号是否已配置(用户名 + 口令都在) */
|
||||
function fb_admin_account_ready() {
|
||||
return fb_admin_username() !== '' && fb_admin_password_is_set();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验账号口令。
|
||||
* @return int 0=通过 1=账号或口令不对 2=还没配置账号
|
||||
*/
|
||||
function fb_admin_verify_login($user, $pw) {
|
||||
$user = trim((string)$user);
|
||||
$pw = (string)$pw;
|
||||
$u = fb_admin_username();
|
||||
|
||||
if ($u === '' && !fb_admin_password_is_set()) { return 2; }
|
||||
|
||||
// 用户名没配过(老部署只设了口令):只比口令,向后兼容
|
||||
if ($u === '') {
|
||||
return fb_admin_verify_password($pw) ? 0 : 1;
|
||||
}
|
||||
|
||||
$hash = (string)fb_setting('admin.password_hash', '');
|
||||
// 用户名不对也照常跑一次哈希校验,保持耗时一致
|
||||
$pwOk = $hash !== '' ? password_verify($pw, $hash) : fb_admin_verify_password($pw);
|
||||
$uOk = hash_equals($u, $user);
|
||||
return ($uOk && $pwOk) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭一个 curl 句柄(跨版本安全)。
|
||||
* --------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user