Files
YwxAppThink/app/backend/middleware/BackendSchemaMiddleware.php
T
yangwx 18101cf11a feat: 上线前安全加固与发布工程化;appmall 由插件迁移为独立应用
安全(P0)
- 发布包签名:新增 scripts/package_keygen.php、scripts/package_verify.php、
  ywxapp\service\PackageVerifier;FrameworkService::apply() 解压前强制验签
  (ywxapp.framework_package_verify,默认开启)
- JWT 收紧:config/jwt.php 移除公开默认密钥,JwtService::assertStrongSecret()
  校验非空 / 长度≥32 / 已知弱值;.env.production.example 键名由 JWT_SECRET_KEY 修正为 JWT_SECRET
- /api/v1/Article:免登录白名单收窄为只读接口,写操作字段白名单 + assertOwner() 越权校验
- 开发者令牌:查找接口不再回显明文、统一失败文案 + 限流
- TemplateInstaller:文件名白名单 + realpath 归一化 + 目录内断言,修复 Zip Slip;补 use ZipArchive
- 后台登录:接入验证码、失败锁定与登录限流(config/ratelimit.php)
- 缓存 / Session 驱动可由 .env 覆盖(CACHE_DRIVER / SESSION_TYPE),集群部署改 redis
- paycenter 支付日志开关改为 PAY_LOG,不再跟随 APP_DEBUG

工程化 / 交付
- 新增 CHANGELOG.md 与 .env.production.example;composer.lock 入库锁定依赖版本
- 插件离线安装 CLI 增加 --uid,后台上传安装透传 uid,付费插件授权校验可通过
- 授权拒绝文案区分「未携带 uid」与「未找到有效授权」,便于排障
- .gitignore 放行 .env.production.example / .env.addon.example / .gitattributes / public/.htaccess

结构
- appmall 由 addon/appmall 迁移为独立应用 app/appmall(市场 / 开发者中心 / 审核 / 分润)
2026-10-22 00:53:39 +08:00

71 lines
3.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
// +----------------------------------------------------------------------
// | YwxApp [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Author: ywxapp <admin@ywxapp.cn>
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace app\backend\middleware;
use ywxapp\model\BackendAdmin;
/**
* 后台「表结构兜底」中间件(应用级注册于 app/backend/middleware.php)。
*
* 作用:任何进入 /admin/* 的请求(登录页 / 后台首页 / 后台 API / 未注册路由)
* 都先把后台 6 张核心表
* (backend_admin / backend_log / backend_power / backend_role /
* backend_role_access / backend_role_power)
* 一次性补齐,杜绝「线上库缺表 / 老库缺字段 → 1146 Table doesn't exist /
* 1054 Unknown column」首次撞错的问题。
*
* 设计要点(与 AppmallSchemaMiddleware 对称):
* - 幂等且极轻:BaseModel::ensureTableFromInstall() 内部已做进程内 memo,
* 每请求每表最多一次 SHOW TABLES,已建好的库几乎零开销;
* - 无版本号:不做版本比对、不需要迁移脚本,纯探测式兜底;
* - 绝不阻断业务:DB 未连接、账号无 CREATE 权限等异常一律静默吞掉,
* 由后续业务报错暴露(与框架既有自愈引擎的降级策略一致)。
*
* 调用点:BackendAdmin::ensureSchema() 已一站式覆盖全部 6 张表(见该方法循环),
* 无需在每个 backend 模型里反复调,确保「一次请求一个兜底入口」。
*
* @author ywxapp <admin@ywxapp.cn>
*/
class BackendSchemaMiddleware
{
public function handle($request, \Closure $next)
{
try {
BackendAdmin::ensureSchema();
} catch (\Throwable $e) {
// 自愈失败不影响本次请求,由后续业务报错暴露
}
// appmall 菜单兜底:模块迁出 addon/ 后 createMenu 不再执行,
// 这里随 /admin/* 请求幂等注入「应用市场」侧边栏菜单(客户机自动跳过,
// 菜单清单内置于 AppmallMenu 常量)。class_exists 守卫:
// 万一未来移除 appmall 应用,不影响后台。
try {
if (class_exists(\app\appmall\library\AppmallMenu::class)) {
\app\appmall\library\AppmallMenu::ensure();
}
} catch (\Throwable $e) {
// 菜单兜底失败不影响本次请求
}
// 新增后台菜单自愈:与上面 appmall 菜单同构。
// 关键:菜单只靠「访问页面时补录」是补不上的(菜单不存在 ⇒ 点不进去 ⇒ 永不触发),
// 所以放在请求级:database / adminlog / attachment / system 四个入口随请求出现在侧边栏。
try {
\app\backend\library\MenuRegistry::ensure();
} catch (\Throwable $e) {
// 菜单补录失败不影响本次请求
}
return $next($request);
}
}