Skip to content
 
 

Repository files navigation

FlareDrive

面向 Cloudflare R2 的轻量级、自托管文件管理器。FlareDrive 使用 React 与 Vite 提供 Web 文件管理界面,通过 Cloudflare Pages Functions 暴露 WebDAV API,并将文件存储在 R2 中;需要网页登录时,可选用 D1 保存会话。

Cloudflare 免费额度包含 10 GB R2 存储空间和每天 100,000 次 Pages Functions 调用。查看官方价格

简体中文 | English

功能亮点

文件管理

  • 网格和详细信息两种视图,支持按名称、修改时间、类型和大小排序或分组
  • 搜索、面包屑导航以及与浏览器前进/后退同步的目录 URL Hash
  • 桌面端框选、Ctrl/Cmd 多选、Shift 范围选择和右键菜单
  • 移动、复制、重命名、删除、批量下载和复制文件链接
  • 文件夹递归复制、移动和删除,支持将文件直接拖入目标文件夹

上传与缩略图

  • 上传单个或多个文件、整个文件夹,以及拖放文件或文件夹
  • 移动设备支持拍照上传和选择图片或视频
  • 大文件自动使用 R2 Multipart Upload;上传队列支持进度、取消和失败状态
  • 图片、视频和 PDF 上传时生成内容哈希缩略图,并存入隐藏的内部命名空间

预览与编辑

  • 图片缩放查看,浏览器原生音频、视频和 PDF 查看
  • 文本、Markdown 和 HTML 在线编辑、另存为及保存回 R2
  • Markdown 提供预览、分栏和编辑模式;HTML 在 sandbox iframe 中预览
  • ZIP 压缩包内容列表和单文件下载
  • DOCX、PPTX、XLSX、XLS 和 CSV 在独立 sandbox iframe 中本地渲染
  • Office 渲染器按格式延迟加载,打开一种格式不会加载另外两种格式的依赖

访问控制

  • 标准 WebDAV Basic Auth 管理员账号
  • 可选的单账号密码登录、D1 Session 和“退出所有设备”
  • 可选 Cloudflare Turnstile,只保护密码登录接口
  • WebDAV 范围令牌,支持只读 ro、读写 rw 和仅上传 up
  • 可选公开读取,仅开放 GETHEADPROPFIND

界面预览

文件管理与多选

FlareDrive file management

Markdown 编辑与预览

FlareDrive Markdown editor

ZIP 文件预览

FlareDrive ZIP preview

系统架构

flowchart LR
  Browser["Web 应用<br/>React + Vite"]
  WebDAV["/webdav/*<br/>Pages Functions"]
  Auth["/api/auth/*<br/>Pages Functions"]
  R2["R2 Bucket<br/>BUCKET"]
  D1["D1 会话库<br/>AUTH_DB,可选"]
  Office["Office 预览 iframe<br/>opaque origin"]

  Browser -->|WebDAV 请求| WebDAV
  WebDAV --> R2
  Browser -->|密码登录| Auth
  Auth --> D1
  Browser -. "MessageChannel 传输 ArrayBuffer" .-> Office
Loading

主页面先通过已认证的 /webdav 请求下载 Office 文件,再使用一次性 MessageChannelArrayBuffer 传入 iframe。iframe 只包含 sandbox="allow-scripts",没有 allow-same-origin;sandbox 与 CSP 共同禁止网络请求、表单、弹窗、对象、子框架和顶层导航。

主要技术组件:

层级 实现
Web 前端 React 19、MUI 9、Vite 8、TypeScript
API Cloudflare Pages Functions / Workers Runtime
文件存储 Cloudflare R2
登录会话 Cloudflare D1,可选
文档预览 Viewer.js、PDF.js、docx-preview、pptx-preview、SheetJS、Univer

部署到 Cloudflare Pages

前置条件

  • Cloudflare 账号
  • 一个 R2 存储桶
  • 一个与 Cloudflare Pages 连接的 Git 仓库或 Wrangler CLI

Pages 构建设置

将 fork 或克隆后的仓库连接到 Cloudflare Pages,并使用以下设置:

设置
Framework preset None
Build command npm run build
Build output directory build
Root directory 仓库根目录

Cloudflare 绑定

部署前至少配置 R2 绑定:

类型 绑定名称 是否必需 用途
R2 Bucket BUCKET 存储文件和内部缩略图
D1 Database AUTH_DB 仅 Password 模式 保存登录 Session 的哈希和过期时间

配置绑定和环境变量后重新部署。public/_routes.json 只将 /webdav/*/api/auth/* 交给 Pages Functions,其他路径作为静态资源提供。

最小 Basic Auth 配置

默认认证模式是 basic。设置:

FLAREDRIVE_AUTH_MODE="basic"
WEBDAV_USERNAME="admin"
WEBDAV_PASSWORD="replace-with-a-strong-password"

首次访问 WebDAV 时,浏览器或 WebDAV 客户端会显示 HTTP Basic Auth 登录提示。

使用 Wrangler 部署

npm ci
npm run build
npx wrangler pages deploy build --project-name <your-pages-project>

认证与访问控制

模式对比

模式 Web 应用 WebDAV 客户端 主要配置
basic 依赖浏览器 HTTP Basic Auth 管理员账号或范围令牌 WEBDAV_USERNAMEWEBDAV_PASSWORD
password 登录对话框、D1 Session Cookie 仍使用管理员 Basic Auth 或范围令牌 AUTH_DBFLAREDRIVE_LOGIN_ACCOUNTFLAREDRIVE_LOGIN_PRIVATE_KEY
Public Read 无认证读取列表和文件 无认证读取 WEBDAV_PUBLIC_READ="1"

Password 模式只提供一个网页登录账号。WebDAV 客户端继续使用 WEBDAV_USERNAMEWEBDAV_PASSWORD 或范围令牌。

配置 Password 模式

  1. 创建 D1 数据库,并绑定为 AUTH_DB
  2. 执行 Session Schema:
npx wrangler d1 execute <database-name> --remote --file migrations/0001_auth_sessions.sql
  1. 生成密码的 SHA-256:
node -e "const crypto=require('crypto'); console.log(crypto.createHash('sha256').update(process.argv[1]).digest('hex'))" "replace-with-a-strong-password"
  1. 生成 ECDH P-256 私钥:
node -e "const { webcrypto } = require('crypto'); (async () => { const pair = await webcrypto.subtle.generateKey({ name: 'ECDH', namedCurve: 'P-256' }, true, ['deriveKey']); console.log(JSON.stringify(await webcrypto.subtle.exportKey('jwk', pair.privateKey))); })()"
  1. 配置以下变量:
FLAREDRIVE_AUTH_MODE="password"
FLAREDRIVE_LOGIN_ACCOUNT='{"username":"admin","password":"<sha256-hex>"}'
FLAREDRIVE_LOGIN_PRIVATE_KEY='<private-jwk-json>'

网页登录载荷使用临时客户端 ECDH P-256 密钥协商 AES-GCM 密钥后加密。登录成功后,服务端设置不透明的 HttpOnlySameSite=Lax Session Cookie;HTTPS 请求还会设置 Secure。D1 只保存 Session Token 的 SHA-256,不保存原始 Token。

启用 Turnstile

同时配置以下两个值,Password 登录接口才会要求 Turnstile:

FLAREDRIVE_TURNSTILE_SITE_KEY="<turnstile-site-key>"
FLAREDRIVE_TURNSTILE_SECRET_KEY="<turnstile-secret-key>"

Turnstile 不保护 WebDAV Basic Auth,也不会改变范围令牌行为。

WebDAV 范围令牌

先为每个原始 Token Secret 生成 SHA-256,然后将哈希写入 WEBDAV_ACCESS_TOKENS

WEBDAV_ACCESS_TOKENS='[{"username":"phone","password":"<sha256-hex>","access":"rw","includes":["photos/phone/"],"excludes":["photos/phone/private/"]},{"username":"dropbox","password":"<sha256-hex>","access":"up","includes":["uploads/"],"excludes":[]}]'
access 允许的操作
ro GETHEADPROPFIND
rw 所有受支持的 WebDAV 和分片上传操作
up 文件 PUT、分片创建/上传/完成以及分片中止;不能读取、列目录、建目录、复制、移动或删除已有文件

includesexcludes 使用 R2 对象键路径,而不是完整 URL。范围允许路径本身和其子路径;例如 photos/phone 不会匹配 photos/phonebookexcludes 优先于 includesCOPYMOVE 的目标也必须位于允许范围内。

WebDAV 客户端登录时输入 Token 的 username原始 Token Secret,不是配置中的 SHA-256。范围客户端应直接连接到其允许前缀,例如:

https://<your-domain>/webdav/photos/phone/

up Token 无法创建父目录,因此目标父目录必须已存在;直接上传到存储桶根目录时除外。

绑定和环境变量参考

名称 类型 默认值 说明
BUCKET R2 绑定 主文件存储,必需
AUTH_DB D1 绑定 Password 模式 Session 数据库
FLAREDRIVE_AUTH_MODE 变量 basic basicpassword
WEBDAV_USERNAME Secret/变量 WebDAV 管理员用户名
WEBDAV_PASSWORD Secret WebDAV 管理员密码
WEBDAV_ACCESS_TOKENS Secret 范围令牌 JSON 数组
WEBDAV_PUBLIC_READ 变量 未启用 设置为 1 时公开 GETHEADPROPFIND
FLAREDRIVE_LOGIN_ACCOUNT Secret 单账号用户名和密码哈希 JSON
FLAREDRIVE_LOGIN_PRIVATE_KEY Secret Password 登录使用的 ECDH P-256 私有 JWK
FLAREDRIVE_TURNSTILE_SITE_KEY 变量 Turnstile 前端 Site Key
FLAREDRIVE_TURNSTILE_SECRET_KEY Secret Turnstile 服务端 Secret Key
FLAREDRIVE_SESSION_TTL_SECONDS 变量 86400 普通登录有效期
FLAREDRIVE_REMEMBER_TTL_SECONDS 变量 604800 “保持登录”有效期

生产密钥应使用 Cloudflare Secret 或受保护的环境变量,不要写入 Git。

本地开发

安装与配置

npm ci

复制本地配置模板:

# Windows PowerShell
Copy-Item .dev.vars.example .dev.vars
# macOS / Linux
cp .dev.vars.example .dev.vars

编辑 .dev.vars。使用 Basic 模式时无需初始化 D1;使用 Password 模式时执行:

npx wrangler d1 execute AUTH_DB --local --config wrangler.local.jsonc --file migrations/0001_auth_sessions.sql

启动前后端:

npm run dev
服务 地址 说明
Vite http://127.0.0.1:3601 前端、HMR,并代理 /webdav/api
Wrangler Pages Dev http://127.0.0.1:3602 Pages Functions、Local R2 和 Local D1

打开 http://127.0.0.1:3601。Basic 模式下,前端不会把开发账号直接写入请求头;浏览器在 /webdav/ 返回认证挑战时要求输入凭据。

构建与预览

npm run build
npm run preview

npm run previewhttp://127.0.0.1:3600 只预览已经构建的静态前端,不会启动 Pages Functions。

常用命令

命令 作用
npm run dev 同时启动 Vite 和本地 Pages Functions
npm run dev:frontend 只启动 Vite,端口 3601
npm run dev:functions 只启动 Wrangler Pages Dev,端口 3602
npm run build TypeScript 类型检查并生成生产构建到 build/
npm run preview 预览 build/ 中的静态前端
npm run lint 检查 src/functions/ 和构建配置

WebDAV 客户端

管理员端点:

https://<your-domain>/webdav/

支持的方法:OPTIONSPROPFINDMKCOLHEADGETPOSTPUTCOPYMOVEDELETE。其中 POST 及带查询参数的部分 PUT/DELETE 用于 Web 应用的 R2 Multipart Upload 流程。

Web 应用对小于 100,000,000 字节的文件使用普通 PUT,达到该值时切换到自定义分片上传。普通 WebDAV 客户端通常只使用标准 PUT,不会自动使用 FlareDrive 的分片 API;上传大文件时建议使用 Web 应用。

Basic Auth 会在每次请求中发送 Base64 编码的账号密码。Base64 不是加密,请始终通过 HTTPS 使用生产站点。

预览支持与限制

类型 行为 浏览器内大小限制
图片 Viewer.js 缩放查看 未设置专用限制
音频 / 视频 浏览器原生播放器 未设置专用限制
PDF 新窗口使用浏览器查看;PDF.js 用于生成缩略图 未设置专用限制
文本 / Markdown / HTML 预览、编辑、保存和另存为 2 MiB
ZIP 文件列表和单文件下载 30 MiB
DOCX / PPTX / XLSX / XLS / CSV sandbox iframe 内本地解析和渲染 小于 10 MiB

Office 预览以兼容和快速浏览为目标,复杂字体、动画、宏、嵌入对象或高级公式不保证与桌面 Office 完全一致。项目不会执行 Office 宏。

安全设计

  • Office 和 HTML 预览运行在没有 allow-same-origin 的 sandbox iframe 中;Office iframe 的 sandbox 与 CSP 禁止网络、表单、对象、嵌套 iframe、弹窗和顶层导航;DOCX 额外禁用 altChunk HTML,并在渲染完成后移除链接和导航能力;Markdown 渲染则跳过原始 HTML
  • 上传或下载 HTML、SVG、XHTML 等活动内容时,WebDAV 强制附件响应、nosniff 和 sandbox CSP
  • 内部 _$flaredrive$/ 命名空间不会出现在普通目录列表,并限制为受控缩略图操作
  • Password 模式只在 D1 存储 Session Token 哈希
  • 范围令牌会校验源路径、COPY/MOVE 顶层目标及每个递归派生目标

本项目当前是单账号文件管理器,不包含多租户权限模型、操作审计日志或恶意文件扫描。

项目结构

index.html                     Vite 主入口
office-preview.html            隔离的 Office iframe 入口
src/                           React Web 应用
src/office-preview/            DOCX、PPTX、Spreadsheet iframe 运行时
functions/webdav/              WebDAV Pages Functions 和方法处理器
functions/api/auth/            Password Session API
functions/auth.ts              登录、Turnstile、Cookie 和 D1 Session 工具
migrations/                    D1 Schema
public/_headers                Office iframe CSP 和静态资源 CORS
public/_routes.json            Pages Functions 路由范围
vite.config.ts                 Vite、代理、Worker 和预览分包配置

已知边界

  • Password 模式只支持一个配置账号,不是多用户网盘
  • Public Read 会让任何访问者无需认证即可列出和读取允许的 WebDAV 内容
  • 大目录的递归复制、移动和删除会产生多次 R2 操作

致谢

许可证

MIT

About

Cloudflare R2 file hosting with WebUI, supporting WebDAV (optional scoped access tokens) or secure session login, with online preview and editing.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages