diff --git a/CLOUDFLARE_PAGES_FIX.md b/CLOUDFLARE_PAGES_FIX.md new file mode 100644 index 0000000..0c2e64a --- /dev/null +++ b/CLOUDFLARE_PAGES_FIX.md @@ -0,0 +1,65 @@ +# Cloudflare Pages 部署修复指南 + +## 问题描述 + +在Cloudflare Pages部署时遇到绑定名称冲突: +``` +Error: Failed to publish your Function. Got error: Binding name 'PASSWORD' already in use. +``` + +## 解决方案 + +我们已经将环境变量名从 `PASSWORD` 更改为 `AUTH_PASSWORD` 以避免Cloudflare的保留绑定名称冲突。 + +## 需要的操作 + +### 1. 更新 wrangler.toml 配置 +✅ 已完成 - `PASSWORD` 已更改为 `AUTH_PASSWORD` + +### 2. 更新代码中的引用 +✅ 已完成 - 所有 `process.env.PASSWORD` 已更改为 `process.env.AUTH_PASSWORD` + +### 3. 在 Cloudflare Pages 控制台中设置环境变量 + +由于您提到无法在控制台中直接修改环境变量(因为通过 wrangler.toml 管理),我们需要: + +1. **重新部署项目** - 新的 wrangler.toml 配置会自动设置 `AUTH_PASSWORD` 变量 +2. **验证环境变量** - 确保 `AUTH_PASSWORD` 正确设置 + +### 4. 立即执行步骤 + +现在执行以下命令重新部署: + +```powershell +git add -A +git commit -m "fix: 修复绑定名称冲突 - 将PASSWORD改为AUTH_PASSWORD" +git push origin main +``` + +## 更新说明 + +### 变更的文件: +- `wrangler.toml` - 更新环境变量名称 +- `src/middleware.ts` - 更新认证逻辑 +- `src/app/api/login/route.ts` - 更新登录验证 +- `src/app/api/register/route.ts` - 更新注册逻辑 + +### 环境变量变更: +- `PASSWORD` → `AUTH_PASSWORD` +- 功能保持完全一致,只是变量名称改变 + +## 预期结果 + +部署成功后: +1. 不再出现绑定名称冲突错误 +2. `AUTH_PASSWORD` 环境变量将自动通过 wrangler.toml 设置 +3. 网站应该正常运行,认证功能正常 + +## 验证步骤 + +部署完成后: +1. 访问您的 Cloudflare Pages 网站 +2. 尝试登录(用户名: katelya,密码: your-secure-password-here) +3. 如果能正常登录,说明修复成功 + +如果仍有问题,请检查 Cloudflare Pages 的部署日志。 \ No newline at end of file diff --git a/src/app/api/login/route.ts b/src/app/api/login/route.ts index 138c7c2..0aaa336 100644 --- a/src/app/api/login/route.ts +++ b/src/app/api/login/route.ts @@ -56,10 +56,10 @@ async function generateAuthCookie( authData.password = password; } - if (username && process.env.PASSWORD) { + if (username && process.env.AUTH_PASSWORD) { authData.username = username; // 使用密码作为密钥对用户名进行签名 - const signature = await generateSignature(username, process.env.PASSWORD); + const signature = await generateSignature(username, process.env.AUTH_PASSWORD); authData.signature = signature; authData.timestamp = Date.now(); // 添加时间戳防重放攻击 } @@ -71,9 +71,9 @@ export async function POST(req: NextRequest) { try { // 本地 / localStorage 模式——仅校验固定密码 if (STORAGE_TYPE === 'localstorage') { - const envPassword = process.env.PASSWORD; + const envPassword = process.env.AUTH_PASSWORD; - // 未配置 PASSWORD 时直接放行 + // 未配置 AUTH_PASSWORD 时直接放行 if (!envPassword) { const response = NextResponse.json({ ok: true }); @@ -136,7 +136,7 @@ export async function POST(req: NextRequest) { // 可能是站长,直接读环境变量 if ( username === process.env.USERNAME && - password === process.env.PASSWORD + password === process.env.AUTH_PASSWORD ) { // 验证成功,设置认证cookie const response = NextResponse.json({ ok: true }); diff --git a/src/app/api/register/route.ts b/src/app/api/register/route.ts index c69e0b3..6fd6190 100644 --- a/src/app/api/register/route.ts +++ b/src/app/api/register/route.ts @@ -50,8 +50,8 @@ async function generateAuthCookie(username: string): Promise { timestamp: Date.now(), }; - // 使用process.env.PASSWORD作为签名密钥,而不是用户密码 - const signingKey = process.env.PASSWORD || ''; + // 使用process.env.AUTH_PASSWORD作为签名密钥,而不是用户密码 + const signingKey = process.env.AUTH_PASSWORD || ''; const signature = await generateSignature(username, signingKey); authData.signature = signature; diff --git a/src/middleware.ts b/src/middleware.ts index 99aa4e2..f584906 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -14,7 +14,7 @@ export async function middleware(request: NextRequest) { const storageType = process.env.NEXT_PUBLIC_STORAGE_TYPE || 'localstorage'; - if (!process.env.PASSWORD) { + if (!process.env.AUTH_PASSWORD) { // 如果没有设置密码,重定向到警告页面 const warningUrl = new URL('/warning', request.url); return NextResponse.redirect(warningUrl); @@ -29,7 +29,7 @@ export async function middleware(request: NextRequest) { // localstorage模式:在middleware中完成验证 if (storageType === 'localstorage') { - if (!authInfo.password || authInfo.password !== process.env.PASSWORD) { + if (!authInfo.password || authInfo.password !== process.env.AUTH_PASSWORD) { return handleAuthFailure(request, pathname); } return NextResponse.next(); @@ -46,7 +46,7 @@ export async function middleware(request: NextRequest) { const isValidSignature = await verifySignature( authInfo.username, authInfo.signature, - process.env.PASSWORD || '' + process.env.AUTH_PASSWORD || '' ); // 签名验证通过即可 diff --git a/wrangler.toml b/wrangler.toml index 16a2854..d07ffca 100644 --- a/wrangler.toml +++ b/wrangler.toml @@ -1,5 +1,20 @@ -name = "katelyatv" -compatibility_date = "2024-09-01" +name = "katelyat[env.preview.vars] +NEXT_PUBLIC_STORAGE_TYPE = "d1" +NEXT_PUBLIC_SITE_NAME = "KatelyaTV" +NEXT_PUBLIC_SITE_DESCRIPTION = "高性能影视播放平台" +NEXTAUTH_URL = "https://your-domain.pages.dev" +USERNAME = "katelya" +AUTH_PASSWORD = "your-secure-password-here" +IMAGE_PROXY_ENABLED = "true" +CACHE_TTL = "3600" +CORS_ORIGIN = "*" +RATE_LIMIT_MAX = "100" +RATE_LIMIT_WINDOW = "60000" +HEALTH_CHECK_ENABLED = "true" +HEALTH_CHECK_INTERVAL = "30" +LOG_LEVEL = "info" +LOG_FORMAT = "json" +NODE_ENV = "production"_date = "2024-09-01" compatibility_flags = ["nodejs_compat"] pages_build_output_dir = ".vercel/output/static" @@ -20,7 +35,7 @@ NEXT_PUBLIC_SITE_NAME = "KatelyaTV" NEXT_PUBLIC_SITE_DESCRIPTION = "高性能影视播放平台" NEXTAUTH_URL = "https://your-domain.pages.dev" USERNAME = "katelya" -PASSWORD = "your-secure-password-here" +AUTH_PASSWORD = "your-secure-password-here" IMAGE_PROXY_ENABLED = "true" CACHE_TTL = "3600" CORS_ORIGIN = "*"