ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

DBX 官网 Cloudflare Worker 部署指南:贡献者证书 GitHub 认证与匿名 Issue 提交

DBX 官网 Cloudflare Worker 部署指南:贡献者证书 GitHub 认证与匿名 Issue 提交 DBX 官网 Cloudflare Worker 部署指南贡献者证书 GitHub 认证与匿名 Issue 提交【免费下载链接】dbx15MB轻量级跨平台数据库客户端、数据库管理工具。支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server 等。15MB, lightweight, cross-platform database client. Supports MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, SQL Server and more.项目地址: https://gitcode.com/t8y2/dbx本文基于 DBX 官网docs/目录下的 Next.js 静态站 Cloudflare Worker的部署文档 CONTRIBUTORS.md 与仓库内真实实现代码展开系统讲解两类线上功能的完整配置流程一是贡献者页面基于 GitHub OAuth 的身份验证与贡献证书资格判定二是无需登录的匿名 Issue 提交含滚动限流、AI 草稿生成、GitHub App 自动开 Issue 与 R2 截图存储。读完本文你可以独立为一个t8y2/dbx同类站点完成 Worker 的密钥配置、GitHub OAuth App / GitHub App 创建并理解限流与草稿状态机的底层实现。站点 Worker 总体结构静态资源、API 路由与 Durable Object在配置任何密钥之前需要先理解 Worker 的职责边界。docs/wrangler.json 声明了整个部署单元的拓扑{ name: dbx, compatibility_date: 2026-05-07, main: ./worker.ts, assets: { directory: ./out, binding: ASSETS, not_found_handling: 404-page, run_worker_first: [ /api/*, /tr, /tr/*, /issue, /issue/, /issues, /issues/, /cn/issues, /cn/issues/, /en/issues, /en/issues/ ] }, r2_buckets: [ { binding: ISSUE_IMAGES, bucket_name: dbx } ], durable_objects: { bindings: [ { name: ISSUE_LIMITER, class_name: IssueSubmissionLimiter } ] }, migrations: [ { tag: v1, new_sqlite_classes: [IssueSubmissionLimiter] } ] }从这份配置可以读出三层结构静态资源层./outNext.js 静态导出产物通过ASSETS绑定提供未命中路由返回站点自身的 404 页面Worker 拦截层run_worker_first列出的路径会先经过 worker.ts 处理——所有/api/*端点、已下线土耳其语文档路由/tr/*308 重定向到英文以及/issue、/issues等匿名反馈别名路由有状态层R2 bucketIssue 截图存储与一个名为IssueSubmissionLimiter的 Durable Object限流计数与草稿状态机并使用 SQLite 存储迁移v1初始化。worker.ts 的默认导出fetch入口即按此顺序分发先处理 Issue 路由重定向与/api端点未匹配的/api路径直接返回 JSON 404注释说明这是为了防止 API 请求落入被边缘缓存的 HTML 404 页其余请求回落ASSETS并对/_next/static/与图片资源附加长期缓存头worker.ts#L105-L109。贡献者页面资格规则与 GitHub OAuth 证书认证谁有资格领取贡献证书贡献者页面路由/[lang]/contributors由 contributors/page.tsx 渲染的数据来自构建期生成的静态快照 data/contributors.json。其资格规则在 CONTRIBUTORS.md 中有明确定义只有向t8y2/dbx合并过至少一个 Pull Request 的账号才被判定为合格贡献者提交commit数量仅作为附加展示指标本身不授予资格。这一规则由数据同步脚本 update-contributors.mjs 在构建期执行脚本并行拉取仓库信息、/contributors?anon0与所有已关闭 PR逐条统计merged_at非空的 PR 数量过滤掉机器人账号后仅保留mergedPullRequests 0的用户并排序输出。源码中的注释直接印证了文档描述// Commit counts enrich merged-PR contributors but never grant eligibility alone. const contributor contributors.get(entry.login.toLowerCase()); if (contributor) contributor.commits entry.contributions || 0;update-contributors.mjs#L93-L98展示层的排序与去重逻辑同样在仓库中可查按 commits、merged PR 数、login 字母序三级排序见 contributorActivity.ts 的sortContributorActivity按小写 login 去重见 contributors.ts 的dedupeContributors。创建 GitHub OAuth App按 CONTRIBUTORS.md 的要求创建 OAuth App 时填写Homepage URLhttps://dbxio.comAuthorization callback URLhttps://dbxio.com/api/auth/github/callback关键点是该 OAuth 流程不请求任何仓库 scopeWorker 换取 access token 后仅调用GET /user读取公开身份随后立即丢弃 tokenworker.ts#L258-L259 注释写明 “The access token is intentionally discarded after reading the public identity”。这意味着站点只保存login、头像与个人主页链接不会长期持有用户凭据。配置 OAuth 相关 Worker 密钥在docs/目录下为已部署的 Worker 配置pnpm dlx wrangler secret put GITHUB_CLIENT_ID pnpm dlx wrangler secret put GITHUB_CLIENT_SECRET pnpm dlx wrangler secret put SESSION_SECRETSESSION_SECRET应为随机生成的至少 32 字节值。它用于 HMAC-SHA256 签名两类无状态 CookieCookie作用有效期签名载荷dbx_oauth_state存放 OAuthstate PKCEverifier 回跳路径10 分钟OAuthStatedbx_contributor_session登录会话7 天SessionUserlogin、头像、主页 URL、过期时间两个 Cookie 均为HttpOnly; Secure; SameSiteLaxworker.ts#L181-L183。非生产回跳域名GITHUB_OAUTH_CALLBACK_URL生产环境的回跳地址默认拼接为${请求 origin}/api/auth/github/callback。如果测试环境的回跳域名与 OAuth App 注册的不一致需要额外配置pnpm dlx wrangler secret put GITHUB_OAUTH_CALLBACK_URL其取值必须与 OAuth App 中注册的 callback 完全一致。源码中该密钥的读取逻辑见 worker.ts#L214const callbackUrl env.GITHUB_OAUTH_CALLBACK_URL || \${url.origin}/api/auth/github/callback且 authorize 与 token 交换两处请求都使用同一个callbackUrl保证redirect_uri 参数一致。OAuth 完整流程含 PKCEGET /api/auth/github/start的实现worker.ts#L206-L231比文档描述多出几层安全细节缺失GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET/SESSION_SECRET任一项时返回503requiredConfig检查生成随机state与 48 字节verifier按S256计算code_challenge一并发给 GitHub 授权端点——即启用了 PKCEreturnTo参数经sanitizeReturnTo校验只接受以/开头且不是//的站内路径否则回落到/en/contributors杜绝开放重定向回调端finishOAuthworker.ts#L233-L273校验签名 Cookie 中state与 URL 参数一致且未过期携带code_verifier换取 token成功后清除 state Cookie、写入 7 天会话 Cookie 并 302 回跳。上述行为的回归测试见 worker.test.ts签名载荷的 round-trip 与篡改拒绝test(signed OAuth payloads round-trip and reject tampering, ...)、//evil.example与绝对 URL 被重置为/en/contributors的断言worker.test.ts#L11-L15。匿名 Issue 提交限流、AI 草稿、GitHub App 与截图存储路由与限流模型/issue与/issues含/cn/issues、/en/issues路由对 GET 请求返回 308 重定向到按Accept-Language本地化的/cn/issue或/en/issueissueRedirectPathworker.ts#L530-L534测试见 worker.test.ts#L17-L22。文档明确说明创建草稿时同时消耗 per-IP 与临时会话两条各 8 次/小时的滚动限额最终提交不再消耗额度且刻意不引入 Cloudflare Turnstile防滥用完全依靠滚动窗口 会话签名 Origin 校验verifyIssueOrigin要求Origin头与请求 URL 同源。限额常量化定义在 issueSubmission.ts#L1-L12export const ISSUE_RATE_LIMIT 8; export const ISSUE_RATE_WINDOW_MS 60 * 60 * 1000; // 1 小时 export const ISSUE_DRAFT_TTL_MS 30 * 60 * 1000; // 草稿 30 分钟 export const ISSUE_CLAIM_TTL_MS 2 * 60 * 1000; // 提交占用 2 分钟滚动窗口的核心算法consumeRollingLimitissueSubmission.ts#L193-L205在 1 小时窗口内保留全部时间戳超过 8 条即拒绝并返回最早的resetAtDurable Object 侧还会为窗口末尾时间戳设置 alarm窗口结束后自动deleteAll()清理worker.ts#L628-L630因此限额状态不会无限累积。测试用例直接验证了“8 次放行、第 9 次拒绝、1 小时后释放”这一行为issueSubmission.test.ts#L13-L28。IP 与会话身份均不以明文存储两者分别经HMAC-SHA256(secret, ip: IP)与HMAC-SHA256(secret, session: sessionId)哈希后映射到独立的 Durable Object 实例ip:hash/session:hashWorker 再向各自实例的/limit/consume端点请求消耗额度worker.ts#L314-L322、L413-L424。配置 GitHub AppIssues 写权限匿名反馈最终通过 GitHub App 以仓库身份发布 Issue。按 CONTRIBUTORS.mdGitHub App 应仅安装到t8y2/dbx仓库权限只授予Issues: Read and write然后配置pnpm dlx wrangler secret put GITHUB_APP_ID pnpm dlx wrangler secret put GITHUB_APP_PRIVATE_KEY_B64 pnpm dlx wrangler secret put ISSUE_RATE_LIMIT_SECRET参数要点GITHUB_APP_PRIVATE_KEY_B64接受 GitHub App 下载 PEM 私钥后的 base64 单行值生成命令base64 private-key.pem | tr -d \nISSUE_RATE_LIMIT_SECRET独立的、至少 32 字节的随机值用于会话 Cookie 与身份哈希签名SESSION_SECRET只作为回退使用目的是不破坏已部署的 Worker回退逻辑见 worker.ts#L308-L312 的issueRuntimeSecret源码对私钥做了兼容处理支持RSA PRIVATE KEYPKCS#1自动包裹成 PKCS#8 后再用 WebCrypto 加载issueSubmission.ts#L130-L145。配置 OpenAI 兼容多模态 AI 提供方pnpm dlx wrangler secret put ISSUE_AI_API_BASE pnpm dlx wrangler secret put ISSUE_AI_API_KEY pnpm dlx wrangler secret put ISSUE_AI_MODELISSUE_AI_API_BASE的写法有三种均可识别issueAiEndpoint归一化逻辑issueSubmission.ts#L239-L244以主机名结尾、以/v1结尾、或直接以/chat/completions结尾。文档同时要求模型必须接受image_urldata URL——因为截图会以data:mime;base64,...形式内联进 user messageissueSubmission.ts#L326-L331。AI 请求的实际参数固定为temperature: 0.2、max_tokens: 6000超时按是否带截图区分纯文本 45 秒、含图 90 秒issueAiRequestTimeoutMs测试见 issueSubmission.test.ts#L59-L63。系统提示词严格要求模型只保留描述与截图中可确认的事实、缺失信息标注“未提供”、对截图中的密码/Token/连接串脱敏issueSubmission.ts#L250-L271模型输出被解析为{type,title,summary,body}的 JSON 草稿parseIssueAiResponse。R2 截图存储与公共地址wrangler.json 将ISSUE_IMAGES绑定到既有的dbxR2 bucket。生成图片的公共 URL 默认发布于https://dl.dbxio.com若 bucket 的公共访问域名变更需设置密钥ISSUE_IMAGE_PUBLIC_BASE_URL覆盖默认值worker.ts#L382。对象键按issue-feedback/年/月/draftId/序号-UUID.扩展名组织issueImageObjectKeyissueSubmission.ts#L465-L469上传时写入public, max-age31536000, immutable缓存头上传中途失败会回滚已上传对象。截图本身有严格限制最多 3 张、单张 ≤5MB、合计 ≤12MB且只信任文件魔数PNG/JPEG/WebP 头字节不信任浏览器声明的 MIMEreadIssueImagesissueSubmission.test.ts#L51-L57 有对应测试。ISSUE_GITHUB_REPOSITORY仅在针对其他仓库联调时才需要设置生产默认t8y2/dbx该默认值同样出现在 issueSubmission.ts#L403。提交链路草稿状态机与幂等一次完整的匿名提交包含两个端点对应 Durable Object 中IssueSubmissionLimiter类的四个内部端点worker.ts#L536-L631POST /api/issues/draftworker.ts#L406-L464创建/复用 24 小时临时会话 CookieSameSiteStrict→ 校验 Origin → 消耗 IP 与会话两条滚动限额任一超限返回 429 retryAfter秒数→ 校验描述46000 字符→ 调 AI 生成可编辑草稿 → 在会话的 Durable Object 中draft/create一条 30 分钟 TTL 的记录返回draftId、preview与剩余限额POST /api/issues/submitworker.ts#L466-L524不重复消耗限额 →draft/claim在 Durable Object 事务内把草稿从ready置为submitting2 分钟占用锁重复提交同一draftId会得到completed结果直接返回既有 Issue 链接从而实现提交幂等随后上传截图、生成带标题前缀[Bug]/[Feature]/[Question]/[Compatibility]与仓库 Issue 标签的正文经 GitHub App JWTRS256iatnow-60、expnow540换取仅issues:write权限的 installation token 创建 Issue成功后draft/complete记录submitted状态与 Issue 编号任何环节抛错都会清理已传截图并draft/release释放占用。GitHub App 的 token 最小化值得注意Worker 每次只申请“当前仓库 issues write”的 installation tokenissueSubmission.ts#L402-L426且整个流程不使用用户身份Issue 以仓库身份发布。部署密钥速查与验证把 CONTRIBUTORS.md 的全部配置项汇总如下均在docs/目录执行wrangler secret put密钥用途取值要求GITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET贡献者页面 OAuth 登录GitHub OAuth App 凭据缺一即返回 503SESSION_SECRET签名 state/会话 Cookie随机值 ≥32 字节GITHUB_OAUTH_CALLBACK_URL非生产回跳域名覆盖与 OAuth App 注册的 callback 一致GITHUB_APP_ID匿名 Issue 发布仅安装于t8y2/dbx的 AppGITHUB_APP_PRIVATE_KEY_B64App 私钥base64 private-key.pem \| tr -d \nISSUE_RATE_LIMIT_SECRET限流会话签名/身份哈希独立随机值 ≥32 字节SESSION_SECRET仅作回退ISSUE_AI_API_BASEOpenAI 兼容端点可止于 host、/v1或/chat/completionsISSUE_AI_API_KEY/ISSUE_AI_MODEL凭证与模型模型需支持image_urldata URLISSUE_IMAGE_PUBLIC_BASE_URL截图公共域名默认https://dl.dbxio.com仅在公共域名变更时设置ISSUE_GITHUB_REPOSITORY联调目标仓库仅联调时设置生产默认t8y2/dbx改动后可借助仓库自带的测试验证关键行为限流窗口issueSubmission.test.ts、AI 响应解析与标题前缀归一化、魔数检测以及 Worker 层的签名载荷、开放重定向防护、Issue 路由 308 与静态缓存头worker.test.ts。综上DBX 官网把“贡献者证书”与“匿名反馈”两个看似独立的功能统一收敛在同一个 Cloudflare Worker 里OAuth 侧坚持“最小 scope 即用即弃 token 有状态签名 Cookie”反馈侧则以 Durable Object 事务实现跨实例一致的滚动限流与幂等提交——两者的密钥、路由与存储绑定全部由 wrangler.json 与 CONTRIBUTORS.md 中的配置项显式声明可按上表逐项完成部署。【免费下载链接】dbx15MB轻量级跨平台数据库客户端、数据库管理工具。支持 MySQL、PostgreSQL、SQLite、Redis、MongoDB、DuckDB、ClickHouse、SQL Server 等。15MB, lightweight, cross-platform database client. Supports MySQL, PostgreSQL, SQLite, Redis, MongoDB, DuckDB, ClickHouse, SQL Server and more.项目地址: https://gitcode.com/t8y2/dbx创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表