在Next.js中使用Supabase Storage的客户端上传时,如何在服务端对文件进行校验?

前端开发 2026-07-09

我有一个使用应用路由的Next.js应用,针对画廊功能有两个独立的上传路径,但我意识到服务器端的安全检查被绕过了。

安全路径(Server Action)- 验证魔术字节并强制执行10MB限制:

// app/actions/upload-gallery-image.ts
"use server";

function detectImageType(bytes: Uint8Array): string | null {
  if (bytes[0] === 0xFF && bytes[1] === 0xD8 && bytes[2] === 0xFF) return "image/jpeg";
  if (bytes[0] === 0x89 && bytes[1] === 0x50) return "image/png";
  // ...
}

export async function uploadGalleryImage(formData: FormData) {
  const file = formData.get("file") as File;
  if (file.size > 10 * 1024 * 1024) return { error: "10MB limit" };

  const bytes = new Uint8Array(await file.arrayBuffer());
  if (!detectImageType(bytes)) return { error: "Invalid file type" };

  await supabase.storage.from("gallery").upload(path, file);
}

客户端组件实际使用的路径——直接上传到Supabase存储,绕过了上述所有检查:

// app/(dashboard)/gallery/GalleryPageClient.tsx
"use client";

async function handleUpload() {
  for (const file of selectedFiles) {
    if (file.size > 50 * 1024 * 1024) { // only client-side check, 50MB not 10MB
      alert("too large");
      continue;
    }
    // Uploads directly — no magic byte check, no server validation
    const { error } = await supabase.storage
      .from("gallery")
      .upload(storagePath, file, { contentType: file.type });
  }
}

客户端组件直接使用Supabase JS SDK(以anon密钥初始化),因此完全跳过了具有正确安全逻辑的服务器端Action。

我想要的:

  • 所有上传都经过服务器端Action,以便始终强制执行魔术字节验证和文件大小限制
  • 支持多文件上传并为每个文件提供一个进度指示
  • 保持用户体验的响应性(上传时不冻结界面)

我考虑过的方案:

  • 对每个文件循环调用服务器端Action,但FormData的每个键只能放一个文件,且服务器端Action不能返回上传进度
  • 改用一个API路由 (/api/upload) ——但这样就会失去服务器端Action的简洁性
  • 通过Supabase存储桶策略强制限制 ——但这只覆盖大小,不涵盖魔术字节

问题: 在Next.js App Router中,处理必须通过服务器端验证(魔术字节、文件类型)的多文件上传,同时保持客户端界面响应性的推荐模式是什么?我应该转向API路由,还是有办法让服务器端Action在这里工作?

环境:

  • Next.js 15(App Router)
  • @supabase/ssr 0.5.2
  • @supabase/supabase-js 2.49.4

解决方案

看起来这是因为你在执行Supabase客户端函数,而不是服务器端的Action。

你可以切换使用服务器端Action,通过在客户端直接导入并执行服务器端Action来实现,然后在Supabase中添加特定规则以禁用客户端上传

如果你需要上传进度,你必须使用API路由,这是唯一可行的方案。你会失去简洁性,但如果你确实需要上传进度,这其实并不是你需要过于担心的问题

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章