Skip to content
cccskills
FreePublished on GitHub

storage-url-safety

当使用 MinIO/OSS/S3 等对象存储、设计文件上传下载功能时触发。提供存储 URL 策略选择规范,防止 URL 过期、访问失败等问题。

The English summary is being prepared. Showing the original description.

Works withAWS
See how to install

Files included (1)

  • SKILL.md7.6 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

存储 URL 策略选择规范

当使用 MinIO/OSS/S3 等对象存储时,正确选择 URL 生成策略。


陷阱 #1: 头像等长期资源使用预签名 URL

场景: 头像、Logo、商品图等需要长期访问的资源

问题根因

预签名 URL 有时效限制(MinIO/S3 最大 7 天),头像等长期资源会过期导致无法访问。

错误示例

// ❌ 错误: 预签名 URL 最大 7 天,头像会过期
String avatarUrl = minioService.getPresignedUrl(filePath, 60 * 24 * 365);
// IllegalArgumentException: expiry must be minimum 1 second to maximum 7 days

// ❌ 错误: 即使设置 7 天,头像也会在 7 天后失效
String avatarUrl = minioService.getPresignedUrl(filePath, 60 * 24 * 7);
// 7 天后用户头像显示"图片加载失败"

正确做法

// ✅ 方案1: 公开 URL(需配置 bucket 公开读)
public String getPublicUrl(String filePath) {
    String endpoint = minioConfig.getEndpoint();
    if (endpoint.endsWith("/")) {
        endpoint = endpoint.substring(0, endpoint.length() - 1);
    }
    return endpoint + "/" + minioConfig.getBucketName() + "/" + filePath;
}

String avatarUrl = minioService.getPublicUrl(filePath);
// 返回: http://minio:9000/bucket/avatars/xxx.jpeg

// ✅ 方案2: CDN URL(生产环境推荐)
String avatarUrl = cdnService.getCdnUrl(filePath);
// 返回: https://cdn.example.com/avatars/xxx.jpeg

URL 策略选择表

资源类型推荐策略有效期适用场景示例
头像/Logo公开 URL / CDN永久需长期访问用户头像、企业 Logo
商品图片公开 URL / CDN永久需长期访问电商商品图、文章配图
公开文档公开 URL / CDN永久需长期访问用户手册、API 文档
临时文件预签名 URL1h-7d下载凭证导出的 Excel、临时分享
私密文档预签名 URL15min-1h临时授权合同、财务报表
上传凭证预签名 URL5min-30min客户端直传前端直传 OSS

陷阱 #2: 公开 URL 的 Bucket 未配置公开读

场景: 使用公开 URL 但 bucket 策略未配置

错误示例

// ✅ 代码正确生成公开 URL
String avatarUrl = minioService.getPublicUrl(filePath);
// 返回: http://minio:9000/bucket/avatars/xxx.jpeg

// ❌ 但 bucket 未配置公开读,访问返回 403 Forbidden

正确做法

MinIO 配置公开读:

# 方案1: 使用 mc 命令配置(推荐)
mc anonymous set download minio/bucket/avatars

# 方案2: 使用 bucket policy
mc admin policy attach minio readonly --user=public

Bucket Policy 示例:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"AWS": ["*"]},
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::bucket/avatars/*"]
    }
  ]
}

阿里云 OSS 配置:

# 设置 bucket 公共读
ossutil64 set-acl oss://bucket-name public-read

# 或只设置特定目录
ossutil64 set-acl oss://bucket-name/avatars/ public-read --recursive

陷阱 #3: 预签名 URL 的有效期设置不当

场景: 临时文件下载链接有效期过长或过短

规范

场景推荐有效期说明
客户端直传凭证5-30 分钟上传时间通常很短
临时分享链接1-24 小时用户可能稍后下载
导出文件下载1-7 天用户可能多次下载
私密文档查看15-60 分钟安全性要求高

错误示例

// ❌ 错误: 客户端直传凭证有效期 7 天,安全风险高
String uploadUrl = minioService.getPresignedUrl(filePath, 60 * 24 * 7);

// ❌ 错误: 导出文件下载链接只有 5 分钟,用户可能来不及下载
String downloadUrl = minioService.getPresignedUrl(filePath, 5);

正确做法

// ✅ 客户端直传凭证: 15 分钟
String uploadUrl = minioService.getPresignedUrl(filePath, 15);

// ✅ 导出文件下载: 24 小时
String downloadUrl = minioService.getPresignedUrl(filePath, 60 * 24);

// ✅ 私密文档查看: 30 分钟
String viewUrl = minioService.getPresignedUrl(filePath, 30);

陷阱 #4: 前端直传时未校验文件类型和大小

场景: 前端直传 OSS,后端生成上传凭证

错误示例

// ❌ 错误: 未校验文件类型和大小,任何文件都能上传
@PostMapping("/upload/token")
public ApiResponse<String> getUploadToken(@RequestParam String filename) {
    String uploadUrl = minioService.getPresignedUrl("uploads/" + filename, 15);
    return ApiResponse.success(uploadUrl);
}

正确做法

// ✅ 后端校验文件类型和大小
@PostMapping("/upload/token")
public ApiResponse<UploadToken> getUploadToken(
    @RequestParam String filename,
    @RequestParam String contentType,
    @RequestParam Long fileSize) {

    // 校验文件类型
    List<String> allowedTypes = Arrays.asList("image/jpeg", "image/png", "image/gif");
    if (!allowedTypes.contains(contentType)) {
        return ApiResponse.error("不支持的文件类型");
    }

    // 校验文件大小(5MB)
    if (fileSize > 5 * 1024 * 1024) {
        return ApiResponse.error("文件大小不能超过 5MB");
    }

    // 生成安全的文件名(防止路径遍历)
    String safeFilename = UUID.randomUUID() + getExtension(filename);
    String filePath = "avatars/" + LocalDate.now() + "/" + safeFilename;

    String uploadUrl = minioService.getPresignedUrl(filePath, 15);
    return ApiResponse.success(new UploadToken(uploadUrl, filePath));
}

陷阱 #5: CDN 回源配置错误

场景: 使用 CDN 加速但回源配置不正确

错误示例

// ✅ 代码正确返回 CDN URL
String avatarUrl = "https://cdn.example.com/avatars/xxx.jpeg";

// ❌ 但 CDN 回源配置错误:
// 1. 回源 Host 未设置为 MinIO endpoint
// 2. 回源协议未设置为 HTTP
// 3. 回源路径未包含 bucket 名称
// 导致 CDN 返回 404 或 403

正确做法

阿里云 CDN 回源配置:

回源 Host: minio.example.com
回源协议: HTTP
回源地址: minio.example.com:9000
回源路径: /bucket${uri}

腾讯云 CDN 回源配置:

源站类型: 自有源
源站地址: minio.example.com:9000
回源协议: HTTP
回源 Host: minio.example.com
回源路径: /bucket${uri}

检查清单(存储 URL 策略)

URL 策略选择:

  • 头像/Logo 是否使用公开 URL 或 CDN
  • 临时文件是否使用预签名 URL
  • 预签名 URL 的有效期是否 ≤ 7 天
  • 预签名 URL 的有效期是否符合业务场景

Bucket 配置:

  • 公开 URL 的 bucket 是否配置了公开读策略
  • 公开读策略是否只针对特定目录(如 avatars/)
  • 是否配置了 CORS(前端直传需要)

CDN 配置:

  • 生产环境是否使用 CDN 加速
  • CDN 回源 Host 是否正确
  • CDN 回源路径是否包含 bucket 名称
  • CDN 是否配置了缓存规则

安全性:

  • 前端直传是否校验文件类型和大小
  • 文件名是否使用 UUID 防止路径遍历
  • 私密文件是否使用预签名 URL 而非公开 URL

适用范围

  • MinIO
  • 阿里云 OSS
  • 腾讯云 COS
  • AWS S3
  • 七牛云 Kodo
  • 华为云 OBS

规则溯源

> 📋 本回复遵循:`storage-url-safety` - 存储 URL 策略选择规范

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

当设计或修改 REST API 响应结构、处理 API 返回值时触发。防止 API 设计缺陷导致的字段错位、类型歧义等问题。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

当设计或修改 REST API 响应结构、处理 API 返回值,或生成 Excel/CSV/PDF/对账文件等下游产物时触发。防止 API 设计缺陷导致的字段错位、类型歧义,以及生成产物时关键字段缺失但静默成功的问题。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

网关/代理/WAF/CDN 中间件的安全关键词匹配实现规范,防止纯子串匹配误判正常响应内容中的技术术语(如 Cloudflare、502、error)

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

当 API/任务可能执行超过 10 秒(批量数据处理、远程 API 批量调用、全表扫描、跨租户聚合)时触发。防止同步接口被网关 30s 超时切断、用户重复点击触发并发、状态缓存内存泄漏等问题。提供异步任务状态机标准模板。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

Bash 脚本与系统命令规范。禁止行尾注释,强制使用 tee/heredoc 写入,提升命令执行的可维护性。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

当用户操作 .sh、Dockerfile、Makefile、.yml、.yaml 文件,或在 Markdown 中编写 bash 代码块时触发。提供 Bash 编写规范。

The English summary is being prepared. Showing the original description.

doccker/cc-use-exp1.1KUpdated Aug 26, 2026

See all skills by doccker

Report a problem with this skill