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(市场 / 开发者中心 / 审核 / 分润)
This commit is contained in:
1 parent
1d49e6f5ee
commit
18101cf11a
636 files changed
+58517
-9519
No files matched your search
+175
-39
@@ -1,63 +1,199 @@
|
||||
# =============================================================
|
||||
# YwxApp 环境变量模板 (.env.example)
|
||||
# 复制本文件为 .env 后填写真实值。.env 已被 .gitignore 忽略,不会入库。
|
||||
# 注意:键名前后不要留空格(如 `KEY=value`,不能是 `KEY =value`)。
|
||||
# -------------------------------------------------------------
|
||||
# 用法:cp `config.example` `.env` 后填写真实值。
|
||||
# .env 已被 .gitignore 忽略,不会入库。
|
||||
# 注意:等号两侧不要留空格(`KEY=value`,不能是 `KEY= value` 或 `KEY =value`)。
|
||||
# 注释行以 `#` 起始;空值表示「使用代码内默认值」(详见各键说明)。
|
||||
# 章节:① 部署相关 ② 应用基础 ③ 数据库 ④ Redis 缓存 ⑤ 文件存储
|
||||
# ⑥ 多语言 ⑦ JWT/鉴权 ⑧ 邮件 ⑨ 数据同步 ⑩ 支付
|
||||
# ⑪ 应用市场 / 插件密钥 ⑫ 第三方插件(短信等可选)
|
||||
# =============================================================
|
||||
|
||||
# -------------------- 部署 FTP 密码 --------------------
|
||||
# scripts/deploy_wxapp_ftp.ps1 部署脚本读取此密码(优先环境变量 $env:WXAPP_FTP_PASS,其次本文件)
|
||||
WXAPP_FTP_PASS=在此填写FTP密码
|
||||
# ==================== ① 部署相关 ====================
|
||||
# 用于将打包产物(scripts/package_*.php 生成)通过 FTP 推送到生产服务器。
|
||||
# 该变量是「部署者专用钩子」,不依赖项目内任何脚本——
|
||||
# 部署脚本(如 PowerShell / Bash 等)由部署方自行维护,scripts/ 内不存在此脚本。
|
||||
# 部署脚本读取建议:优先环境变量 $env:WXAPP_FTP_PASS / $WXAPP_FTP_PASS,其次本文件。
|
||||
# 仅用于部署发布,与运行期无关;不需要可留空。
|
||||
WXAPP_FTP_PASS=
|
||||
|
||||
# -------------------- 数据库(ThinkPHP 标准键) --------------------
|
||||
# config/database.php 通过 env('DB_*') 读取
|
||||
DB_TYPE=mysql
|
||||
# ==================== ② 应用基础 ====================
|
||||
# 读取:config/app.php — app_debug / app_host
|
||||
APP_DEBUG=true
|
||||
# APP_DEBUG=true → 显示错误、SQL 日志、关闭模板缓存(仅本地/调试用)
|
||||
# APP_DEBUG=false → 生产环境务必设为 false
|
||||
APP_HOST=
|
||||
|
||||
# 官方 API 地址:用于框架在线升级、远程市场同步
|
||||
# 读取:config/ywxapp.php — api_url(env('APP_API_URL', 'https://www.ywxapp.cn'))
|
||||
# 中心站模式留空或指向本机;客户机模式指向中心站域名。
|
||||
APP_API_URL=https://www.ywxapp.cn
|
||||
|
||||
# 市场角色(控制 is_market_client()):center / client / auto
|
||||
# 读取:config/ywxapp.php — market_mode(env('APP_MARKET_MODE', 'auto'))
|
||||
# center → 显式锁定本机为中心站(本地开发推荐,不再依赖 api_url 推断)
|
||||
# client → 显式锁定本机为客户机(应用市场公开入口会主动 404)
|
||||
# auto → api_url 为空/本机时为中心站,否则为客户机(默认,受 api_url 影响)
|
||||
# 显式声明优于 auto,避免后续误改 APP_API_URL 时角色被翻转。
|
||||
APP_MARKET_MODE=auto
|
||||
|
||||
# ==================== ③ 数据库(ThinkPHP 标准键) ====================
|
||||
# 读取:config/database.php
|
||||
# 安装向导(public/install/Installer.php)会重新写入这些键。
|
||||
DB_DRIVER=mysql # default 连接驱动(一般无需修改)
|
||||
DB_TYPE=mysql # connections.mysql.type
|
||||
DB_HOST=127.0.0.1
|
||||
DB_NAME=ywxapp_dev
|
||||
DB_NAME=ywxapp
|
||||
DB_USER=root
|
||||
DB_PASS=
|
||||
DB_PORT=3306
|
||||
DB_CHARSET=utf8
|
||||
DB_PREFIX=wx_
|
||||
DB_PERSISTENT=true
|
||||
DB_CHARSET=utf8mb4 # 建议 utf8mb4(emoji/中文兼容)
|
||||
DB_PREFIX=wxapp_ # 表前缀,安装时由 Installer 统一写入
|
||||
DB_PERSISTENT=true # 是否启用长连接(高并发场景视 MySQL 配置决定)
|
||||
|
||||
# -------------------- 应用 --------------------
|
||||
# config/app.php 通过 env('APP_DEBUG' / 'APP_HOST') 读取
|
||||
APP_DEBUG=true
|
||||
APP_HOST=localhost
|
||||
|
||||
# -------------------- Redis 缓存(ThinkPHP 标准键) --------------------
|
||||
# config/cache.php 通过 env('REDIS_*') 读取
|
||||
# ==================== ④ Redis 缓存(ThinkPHP 标准键) ====================
|
||||
# 读取:config/cache.php
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PORT=6379
|
||||
REDIS_PASSWORD=
|
||||
REDIS_DB=0
|
||||
|
||||
# -------------------- 应用市场 / 插件密钥 --------------------
|
||||
# 后台 JWT 鉴权密钥(ywxapp/service/JwtService.php 读 env('JWT_SECRET'))
|
||||
# 生产环境务必替换为强随机值
|
||||
# HS256 要求密钥 ≥ 256 bits(32 字节),下面为 48 字节 base64 占位,生产请替换为自己的强随机值
|
||||
JWT_SECRET=replace_with_a_48_byte_base64_strong_random_secret_key_2026xxxx
|
||||
# ==================== ⑤ 文件存储 ====================
|
||||
# 读取:config/storage.php — default + drivers.{alioss,qcos}
|
||||
# 取值:local(默认)/ alioss / qcos(其它驱动需在 drivers 中添加)
|
||||
FILE_STORAGE_DRIVER=local
|
||||
|
||||
# 插件签名/下载校验密钥(ywxapp/service/AddonService.php、FrameworkService.php 读 config('ywxapp.addon_secret'))
|
||||
# 中心站与客户机需一致;生产务必替换
|
||||
# ---- 阿里云 OSS(FILE_STORAGE_DRIVER=alioss 时必填)----
|
||||
ALIOSS_ACCESS_KEY=
|
||||
ALIOSS_SECRET_KEY=
|
||||
ALIOSS_ENDPOINT= # 如 oss-cn-hangzhou.aliyuncs.com
|
||||
ALIOSS_BUCKET=
|
||||
ALIOSS_CDN_DOMAIN= # 可选:启用 CDN 加速域名
|
||||
|
||||
# ---- 腾讯云 COS(FILE_STORAGE_DRIVER=qcos 时必填)----
|
||||
QCOS_REGION= # 如 ap-guangzhou
|
||||
QCOS_SECRET_ID=
|
||||
QCOS_SECRET_KEY=
|
||||
QCOS_BUCKET=
|
||||
|
||||
# ==================== ⑥ 多语言 ====================
|
||||
# 读取:config/lang.php — default_lang
|
||||
# 取值:zh-cn / en-us / 自定义语种(需配套语言包)
|
||||
DEFAULT_LANG=zh-cn
|
||||
|
||||
# ==================== ⑦ JWT / 鉴权 ====================
|
||||
# 后台 / 会员 JWT 鉴权密钥
|
||||
# 读取:config/jwt.php — secret(默认值仅为占位,生产务必替换)
|
||||
# HS256 要求 ≥ 256 bits(32 字节)。建议用 `openssl rand -base64 48` 生成。
|
||||
JWT_SECRET=replace_with_48_byte_base64_strong_random_secret_key_xxxxx
|
||||
|
||||
# ==================== ⑧ 邮件 ====================
|
||||
# 读取:config/mail.php
|
||||
# 留空时发信功能不会启用;建议使用 SMTP 协议 + SSL。
|
||||
MAIL_HOST=smtp.example.com
|
||||
MAIL_PORT=465
|
||||
MAIL_SECURE=ssl # ssl / tls / 空
|
||||
MAIL_USERNAME=
|
||||
MAIL_PASSWORD=
|
||||
MAIL_FROM=
|
||||
MAIL_FROM_NAME=YwxApp 应用市场
|
||||
|
||||
# ==================== ⑨ 数据同步 ====================
|
||||
# 读取:config/sync.php — isEnable / baseUrl / key
|
||||
# 用于「主框架 ↔ 业务后台」数据同步通道(开关、目标地址、共享密钥)。
|
||||
SYNC_IS_ENABLE=false
|
||||
SYNC_BASE_URL=https://sync.example.com
|
||||
SYNC_KEY=your-256-bit-secret-key-here
|
||||
|
||||
# ==================== ⑩ 支付 ====================
|
||||
# 读取:config/pay.php
|
||||
# 三重防御(已就位):
|
||||
# 1) 本键默认关闭(防御性默认,避免默认值泄露);
|
||||
# 2) Installer.writeEnv() 会强制把 PAY_MOCK=false 写入 .env;
|
||||
# 3) MarketService / Market 在生产(APP_DEBUG=false)拒绝执行 mock。
|
||||
# 本地调试:显式设 PAY_MOCK=true(须与 APP_DEBUG=true 配对)。
|
||||
PAY_MOCK=false
|
||||
|
||||
# 说明:真实的下单 / 验签 / 回调已收拢到支付中心插件 addon/paycenter(见其 README)。
|
||||
# 下面的 PAY_ALIPAY_* / PAY_WECHAT_* 仍是密钥的唯一来源(不进数据库),插件与核心共用。
|
||||
# 自检:php think paycenter:check --ping(--channel=alipay|wechat|all)
|
||||
|
||||
# ---- 支付宝(证书模式,Yansongda Pay v3.7 的硬性要求)----
|
||||
# 普通公钥模式在该版本已不被识别,必须在开放平台「接口加签方式」切换为证书并下载三份证书。
|
||||
# 私钥可填 PEM 全文、单行 base64,或文件路径;三份证书放 runtime/cert/ 下即可(路径可以是相对路径,
|
||||
# 配 config/pay.php 会按项目根目录解析成绝对路径,避免 Web 入口 CWD 在 public/ 时读不到)。
|
||||
# 文件名随意,只要与下面三个 *_PATH 对得上:官方下载名分别是
|
||||
# appCertPublicKey_*.crt(应用公钥证书)/ alipayCertPublicKey_*.crt(支付宝公钥证书)/ alipayRootCert.crt(根证书)
|
||||
PAY_ALIPAY_MODE=0 # 整数:0=正式 1=沙箱 2=服务商(见 Yansongda\Pay\Pay::MODE_*)
|
||||
PAY_ALIPAY_APP_ID=
|
||||
PAY_ALIPAY_APP_SECRET_CERT= # 应用私钥(或填私钥文件路径)
|
||||
PAY_ALIPAY_APP_PUBLIC_CERT_PATH=runtime/cert/appCertPublicKey.crt
|
||||
PAY_ALIPAY_PUBLIC_CERT_PATH=runtime/cert/alipayCertPublicKey.crt
|
||||
PAY_ALIPAY_ROOT_CERT_PATH=runtime/cert/alipayRootCert.crt
|
||||
# 仅 Windows/未配 curl.cainfo 的 PHP 需要:连网关报 cURL error 60(SSL certificate problem)时,
|
||||
# 下载 https://curl.se/ca/cacert.pem 放本地并在这里指向它;正常服务器留空即可
|
||||
PAY_HTTP_CA=
|
||||
|
||||
# ---- 微信支付(v3;微信已无官方沙箱,mode 恒为 0,只能真实小额支付后退款)----
|
||||
# 商户平台 → API 安全:设置 APIv3 密钥、下载 API 证书(apiclient_cert.pem)与私钥(apiclient_key.pem)
|
||||
PAY_WECHAT_MCH_ID=
|
||||
PAY_WECHAT_APP_ID= # 未单独配置时 mp/mini 也用它
|
||||
PAY_WECHAT_MP_APP_ID= # 公众号 JSAPI(可选,默认取 APP_ID)
|
||||
PAY_WECHAT_MINI_APP_ID= # 小程序(可选,默认取 APP_ID)
|
||||
PAY_WECHAT_SECRET_KEY= # APIv3 密钥
|
||||
PAY_WECHAT_SECRET_CERT= # 商户 API 私钥(PEM / 单行 base64 / 文件路径)
|
||||
PAY_WECHAT_PUBLIC_CERT_PATH=runtime/cert/apiclient_cert.pem
|
||||
# 平台证书(回调验签用)留空即可:SDK 会凭 APIv3 密钥自动下载;
|
||||
# 生产环境建议 php think paycenter:check 触发一次后落到 runtime/cert/wechat/ 并配置 wechat_public_cert_path。
|
||||
|
||||
# ==================== ⑪ 应用市场 / 插件密钥 ====================
|
||||
|
||||
# ---- 开发者令牌:后台「发布到官方市场」与 appmall 插件开发者中心共用 ----
|
||||
# 读取:
|
||||
# config/appmall.php → config('appmall.developer_token')
|
||||
# config/ywxapp.php → config('ywxapp.developer_token')(已与 appmall 同源)
|
||||
# app/backend/controller/Addons.php::submitOfficial() 实际取的是上面这个值
|
||||
# 留空则后台操作时会提示「未配置开发者令牌:请在 .env 设置 APPMARKET_DEV_TOKEN」。
|
||||
APPMARKET_DEV_TOKEN=
|
||||
|
||||
# 开发者账号名(可选,仅用于显示)
|
||||
APPMARKET_DEV_NAME=
|
||||
|
||||
# 远程市场共享密钥:仅当本机作「客户机」连接中心站时需要
|
||||
# 读取:config/appmall.php → config('appmall.remote_token')
|
||||
# 单站点中心站模式留空即可;客户机必须与中心站 APPMARKET_REMOTE_TOKEN 一致。
|
||||
APPMARKET_REMOTE_TOKEN=
|
||||
|
||||
# 连接远程市场时是否校验 SSL 证书(生产建议 true)
|
||||
APPMARKET_SSL_VERIFY=true
|
||||
|
||||
# 平台抽成比例(0~1):插件市场成交时平台分账比例,默认 0.2(20%)
|
||||
APPMARKET_COMMISSION_RATE=0.2
|
||||
|
||||
# 发布前 PHP 语法 + 高危函数扫描(生产建议 true)
|
||||
APPMARKET_SECURITY_SCAN=true
|
||||
|
||||
# ---- 插件签名 / 下载校验密钥(中心站与客户机共享)----
|
||||
# 读取:config/ywxapp.php — addon_secret
|
||||
# 生产务必替换为强随机值;中心站与所有客户机必须一致。
|
||||
ADDON_SECRET=change_me_to_a_strong_addon_secret
|
||||
|
||||
# 是否允许未知来源插件(离线包)安装:true 时跳过远程授权校验
|
||||
# 读取:Env::get('app_debug') && config('ywxapp.unknownsources')
|
||||
# 读取:config/ywxapp.php — unknownsources(仅当 APP_DEBUG=true 时生效)
|
||||
ADDON_UNKNOWN_SOURCES=false
|
||||
|
||||
# 开发者模式开关:开启后允许本地开发/调试插件发布
|
||||
# 读取:Env::get('addon_developer') 或 config('ywxapp.addon_developer')
|
||||
# 开发者模式开关:开启后后台「插件」出现「设计插件」入口
|
||||
# 读取:config/ywxapp.php — addon_developer
|
||||
# 生产务必保持 false(与 APP_DEBUG 解耦的独立开关)。
|
||||
ADDON_DEVELOPER=false
|
||||
|
||||
# 发布到官方公共市场(www.ywxapp.cn)所需令牌,由官方运营分配
|
||||
# 留空则后台「发布到官方市场」会提示先配置;读取:env('APPMARKET_DEV_TOKEN')
|
||||
APPMARKET_DEV_TOKEN=
|
||||
# ==================== ⑫ 第三方插件(按需启用) ====================
|
||||
# 短信插件 addon/smssend 需配置网关(由插件自身 config 维护,不一定走 .env);
|
||||
# 其他插件的配置项请参考各插件 addon/<name>/README.md。
|
||||
|
||||
# -------------------- 应用市场授权校验开关(config/ywxapp.php) --------------------
|
||||
# addon_license_check:控制客户机启用插件时的授权闸门与运行期巡检
|
||||
# false → 关闭校验(开发/自用)
|
||||
# true → 开启;中心站不可达也判定失败并禁用插件(防离线绕过)
|
||||
# offline_tolerant → 开启;仅中心站明确拒绝(吊销/过期/域名不符)才禁用,不可达放行
|
||||
# 说明:此键写在 config/ywxapp.php 中,不在此 .env;此处仅作说明,便于查阅。
|
||||
# 对应代码:ywxapp/service/AddonService.php verifyRuntimeLicense() / checkLicenses()
|
||||
# =============================================================
|
||||
# 提示:以下为「代码硬编码、未走 env()」的项目,仅作备忘。
|
||||
# config/ywxapp.php: addon_license_check=false (运行期授权巡检开关,写死 false;
|
||||
# 如需开启,请直接编辑该文件或后续 PR 改造为 env() 控制)
|
||||
# =============================================================
|
||||
Reference in new issue
Block a user