Typecho CloudStorage
适配Typecho的多存储附件插件。可在后台添加多个阿里云OSS/腾讯云COS/S3兼容驱动,保存后随时切换当前上传目标。
开源地址:https://cnb.cool/qiqinb/typecho-plugin-oss
功能
- 弹窗添加、编辑和切换多个存储驱动
- 阿里云 OSS、腾讯云 COS、AWS S3、MinIO、Cloudflare R2 等 S3 兼容服务
- 临时签名地址、公开地址、CDN 私有源站回源鉴权
- JPEG/PNG 自动压缩为 WebP,可设置质量和最大宽高
- 图片自动纠正方向、去除元数据,超大图片安全跳过
- 可选保留本地副本
- 附件替换生成新对象 Key,避免 CDN 继续命中旧内容
- 删除附件时可同步删除远端对象
- STS / 临时凭证、连接超时、失败重试和脱敏日志
- 旧版平铺配置自动迁移
插件不依赖 Composer 或云厂商 SDK。
安装
- 把 CloudStorage 目录复制到 Typecho 的 /usr/plugins/。
- 确认路径为 /usr/plugins/CloudStorage/Plugin.php,目录名不要修改。
- 在 Typecho 后台「控制台 -> 插件」启用 CloudStorage。
- 进入设置,点击「添加驱动」。
- 保存驱动后,将需要使用的配置设为「当前使用」,最后点击页面底部「保存设置」。
- 先上传一张小图片测试显示、替换和删除。
服务器需要 PHP 7.4 或更高版本,并启用 cURL 和 Hash。自动 WebP 需要 Imagick,或启用了 WebP 的 GD;编码器不可用、内存不足或处理失败时,插件会保留原图上传。
添加存储驱动
阿里云 OSS
- AccessKey ID / Secret:用于 Typecho 上传、读取和删除对象。
- Bucket:只填写 Bucket 名称。
- Endpoint:填写区域 Endpoint,例如 https://oss-cn-hangzhou.aliyuncs.com,不要带 Bucket。
- STS SecurityToken:只有使用临时凭证时才填写。
腾讯云 COS
- SecretId / SecretKey:用于 Typecho 上传、读取和删除对象。
- Bucket:必须包含 APPID,例如 example-1250000000。
- Region:例如 ap-guangzhou。
- Endpoint:通常留空,插件会根据 Region 自动生成。
- 临时密钥 Token:只有使用临时密钥时才填写。
S3 兼容存储
- Access Key ID / Secret Access Key:服务商提供的 S3 凭证。
- Bucket:对象存储桶名称。
- Region:SigV4 签名 Region。服务商没有特别说明时常用 us-east-1。
- Endpoint:AWS S3 可留空;MinIO、R2 等需要填写服务商 Endpoint。
- 寻址方式:MinIO、部分私有部署通常使用路径风格。
附件访问方式
插件不再设置对象 ACL,上传对象完全继承 Bucket 的访问策略。只需要按实际访问场景选择一种方式:
| 方式 | 适用场景 | 文章中的地址 |
|---|---|---|
| 临时签名地址 | 私有 Bucket,浏览器直接访问云存储 | 带有效期的 OSS/COS/S3 签名 URL |
| 公开地址 / 普通 CDN | Bucket 公开读,或 CDN 不需要私有回源签名 | 自定义域名或 Bucket 原站地址 |
| CDN 回源鉴权 | Bucket 私有,CDN 已配置 AK/SK 或私有源站鉴权 | 固定 CDN 域名 + 对象 Key |
私有 COS + CDN AK/SK 回源鉴权
这是一个独立场景,不需要选择公开读,也不需要让插件生成 COS 临时下载地址。
- COS Bucket 保持私有。
- 在 CDN 服务商控制台配置 COS 私有源站,并填写用于回源的 SecretId / SecretKey。
- 插件中添加 COS 驱动,填写用于 Typecho 上传和删除文件的 SecretId / SecretKey。
- 「附件访问方式」选择 CDN 回源鉴权。
- 填写浏览器最终访问的 CDN 域名,例如 https://cdn.example.com。
最终文章地址类似:
https://cdn.example.com/typecho/2026/07/example.webp
浏览器请求 CDN,CDN 使用其控制台中配置的凭据向私有 COS 回源。插件中的凭据不会出现在 CDN URL 中。插件凭据和 CDN 回源凭据可以使用不同的 CAM 子用户,分别授予最小权限。
自动 WebP
默认对新上传的 JPEG/PNG 执行以下处理:
- 自动纠正 JPEG 拍摄方向
- 按最大宽高等比例缩小,默认不超过 2560 × 2560
- 转换为 WebP,默认质量 82
- 去除 EXIF 等图片元数据
- 默认仅在 WebP 体积更小时采用
- 超过安全像素上限时保留原图,避免耗尽 PHP 内存
- 使用 GD 时会按
memory_limit估算处理内存,不足时安全跳过
GIF 默认不处理,以免破坏动画。替换旧附件时,仅当原附件本身是 WebP 才进行 WebP 转换,避免旧 .jpg/.png 路径与实际内容不一致。
多驱动切换
每个新附件都会记录驱动 ID、对象 Key、Bucket 和 Endpoint。切换当前驱动只影响之后上传或替换的附件,旧附件继续使用原驱动。
删除驱动前应先迁移该驱动下的附件。删除配置不会删除云端对象,但缺少原凭据后,私有附件可能无法生成地址或执行删除。
本地副本
- 关闭:只保留远端对象,节省服务器磁盘。
- 开启:远端上传成功后原子写入本地;本地失败会尝试回滚刚上传的远端对象。
插件启用前的本地附件仍按 Typecho 原方式访问。不要直接停用插件来迁移仅存在远端的附件。
Handsome 主题
正常情况下不需要修改主题,插件接管的是 Typecho 1.3.0 核心附件 URL。
如果 Handsome 额外启用了图片代理或缩略图服务:
- 临时签名地址需要足够长的有效期;
- 图片代理必须能访问对应云存储域名;
- 使用 CDN 回源鉴权时,主题应直接使用 CDN 地址,不要再次拼接源站域名。
安全建议
- 使用 RAM/CAM/IAM 子账号,不使用主账号密钥。
- 插件账号只授予目标 Bucket 和对象前缀的上传、读取权限;开启远端删除时再授予删除权限。
- CDN 回源账号只授予 CDN 读取私有源站所需权限。
- 默认只使用 HTTPS。HTTP Endpoint 仅用于可信内网 MinIO。
- Typecho 会把插件配置保存在数据库中,请保护后台账号、数据库和备份。
- Secret 不会写入附件 JSON、文章 HTML 或日志。临时签名 URL 按协议包含 AccessKey ID/SecretId 和短期签名,但不包含 Secret。
开发验证
php tests/lint.php
php tests/run.php
php tests/typecho_compat.php