Google OAuth 生产环境问题排查与解决方案
项目: cbiu.fun
服务器位置: 中国广州
解决时间: 2026-02-04 ~ 2026-02-05 (约 5 小时)
📋 问题清单
问题 1: UntrustedHost 错误
错误信息:
[auth][error] UntrustedHost: Host must be trusted. URL was: https://cbiu.fun/api/auth/session
原因:
NextAuth.js 在生产环境(特别是 Edge Runtime)中需要明确信任主机。
解决方案:
# docker-compose.yml environment: - AUTH_TRUST_HOST=true - AUTH_URL=https://cbiu.fun - GOOGLE_CLIENT_ID=${GOOGLE_CLIENT_ID} - GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET}
提交: 83cb7f5
问题 2: fetch failed - GFW 阻断
错误信息:
[auth][error] TypeError: fetch failed
原因:
服务器在中国大陆,GFW(防火墙)阻止访问 Google 服务。
诊断过程:
# 测试连接 curl -4 https://accounts.google.com # ❌ Timeout curl -4 https://www.baidu.com # ✅ Success # 确认位置 curl ipinfo.io # country=CN
解决方案: 部署 V2Ray 加密代理
2.1 V2Ray 服务器(美国 VPS)
服务器 IP: 216.40.86.126
端口: 10086
协议: VMess + WebSocket
# 创建配置文件 cat > /root/v2ray/config.json << 'EOF' { "inbounds": [{ "port": 10086, "protocol": "vmess", "settings": { "clients": [{"id": "5ea51ecf-032c-4833-b5ea-33ad501a6b7d", "alterId": 0}] }, "streamSettings": { "network": "ws", "wsSettings": {"path": "/v2ray"} } }], "outbounds": [{"protocol": "freedom"}] } EOF # 运行服务器 docker run -d --name v2ray --restart always \ -v /root/v2ray/config.json:/etc/v2ray/config.json \ -p 10086:10086 \ v2fly/v2fly-core:latest run -c /etc/v2ray/config.json # 开放防火墙端口 ufw allow 10086/tcp
2.2 V2Ray 客户端(中国服务器)
# 下载 V2Ray wget https://ghp.ci/https://github.com/v2fly/v2ray-core/releases/download/v5.22.0/v2ray-linux-64.zip unzip v2ray-linux-64.zip -d /usr/local/v2ray # 创建配置文件 cat > /usr/local/v2ray/config.json << 'EOF' { "inbounds": [{ "port": 10808, "protocol": "http", "listen": "127.0.0.1" }], "outbounds": [{ "protocol": "vmess", "settings": { "vnext": [{ "address": "216.40.86.126", "port": 10086, "users": [{"id": "5ea51ecf-032c-4833-b5ea-33ad501a6b7d", "alterId": 0}] }] }, "streamSettings": { "network": "ws", "wsSettings": {"path": "/v2ray"} } }] } EOF # 启动客户端 nohup /usr/local/v2ray/v2ray run -c /usr/local/v2ray/config.json > /var/log/v2ray.log 2>&1 & # 验证代理 curl -x http://127.0.0.1:10808 https://www.google.com # ✅ Success
问题 3: Proxychains 配置路径错误 ⭐
错误现象:
虽然配置了 proxychains,但数据库连接仍被代理,导致应用无法连接数据库。
诊断过程:
# 测试发现 proxychains 读取了错误的配置 docker exec cbiu-website sh -c "proxychains4 node -e \"...\"" # 输出: [proxychains] Strict chain ... 127.0.0.1:9050 ... timeout # ^ 错误的端口!应该是 10808
根本原因:
Alpine Linux 的 proxychains-ng 默认读取 /etc/proxychains/proxychains.conf,而不是 /etc/proxychains.conf。
解决方案:
# Dockerfile # ❌ 错误的路径 COPY proxychains.conf /etc/proxychains.conf # ✅ 正确的路径 RUN mkdir -p /etc/proxychains COPY proxychains.conf /etc/proxychains/proxychains.conf
Proxychains 配置文件 (proxychains.conf):
strict_chain tcp_read_time_out 15000 tcp_connect_time_out 8000 # 排除本地网络,避免数据库连接被代理 localnet 127.0.0.0/255.0.0.0 localnet ::1/128 localnet 172.17.0.0/255.255.0.0 # Docker 默认网桥 localnet 172.18.0.0/255.255.0.0 # 自定义 Docker 网络 [ProxyList] http 127.0.0.1 10808
Docker 启动命令:
# Dockerfile CMD ["proxychains4", "-q", "node", "server.js"]
提交: 2142bbc
问题 4: 数据库连接配置
问题:
容器使用 host network mode,但数据库在 Docker bridge 网络,无法通过 localhost 访问。
解决方案:
# 获取 Docker 网络网关 IP docker network inspect cbiu-website_cbiu-network | grep Gateway # 输出: "Gateway": "172.18.0.1" # 更新 .env 文件 DATABASE_URL=mysql://root:123456@172.18.0.1:3306/cbiu_webside
docker-compose.yml 环境变量:
environment: - HTTP_PROXY=http://127.0.0.1:10808 - HTTPS_PROXY=http://127.0.0.1:10808 - NO_PROXY=localhost,127.0.0.1,db,172.17.0.1,172.18.0.1,172.17.0.0/16,172.18.0.0/16
提交: ea41ef6
问题 5: 缺少 NextAuth 数据库表
错误信息:
The table `accounts` does not exist in the current database.
原因:
生产数据库没有运行 Prisma migrations,缺少 NextAuth 所需的表。
解决方案:
# 手动创建表 docker-compose exec -T db mysql -uroot -p123456 cbiu_webside << 'EOF' CREATE TABLE `accounts` ( `id` VARCHAR(191) NOT NULL, `user_id` VARCHAR(191) NOT NULL, `type` VARCHAR(191) NOT NULL, `provider` VARCHAR(191) NOT NULL, `provider_account_id` VARCHAR(191) NOT NULL, `refresh_token` TEXT NULL, `access_token` TEXT NULL, `expires_at` INT NULL, `token_type` VARCHAR(191) NULL, `scope` VARCHAR(191) NULL, `id_token` TEXT NULL, `session_state` VARCHAR(191) NULL, PRIMARY KEY (`id`), UNIQUE KEY `provider_provider_account_id` (`provider`, `provider_account_id`), KEY `user_id` (`user_id`), CONSTRAINT `accounts_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE `sessions` ( `id` VARCHAR(191) NOT NULL, `session_token` VARCHAR(191) NOT NULL, `user_id` VARCHAR(191) NOT NULL, `expires` DATETIME(3) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `session_token` (`session_token`), KEY `user_id` (`user_id`), CONSTRAINT `sessions_user_id_fkey` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE `verification_tokens` ( `identifier` VARCHAR(191) NOT NULL, `token` VARCHAR(191) NOT NULL, `expires` DATETIME(3) NOT NULL, UNIQUE KEY `token` (`token`), UNIQUE KEY `identifier_token` (`identifier`, `token`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; EOF
问题 6: users 表结构不完整
错误信息:
The column `cbiu_webside.users.name` does not exist in the current database. Null constraint violation on the fields: (`username`)
原因:
- 缺少 NextAuth 所需的列:
name,email_verified,image username和password_hash设置为 NOT NULL,但 Google OAuth 不提供这些字段
解决方案:
# 添加缺失的列 docker-compose exec -T db mysql -uroot -p123456 cbiu_webside << 'EOF' ALTER TABLE users ADD COLUMN name VARCHAR(191) NULL AFTER id, ADD COLUMN email_verified DATETIME(3) NULL AFTER email, ADD COLUMN image VARCHAR(191) NULL AFTER email_verified; EOF # 修改为可选字段 docker-compose exec -T db mysql -uroot -p123456 cbiu_webside << 'EOF' ALTER TABLE users MODIFY COLUMN username VARCHAR(191) NULL; ALTER TABLE users MODIFY COLUMN password_hash VARCHAR(191) NULL; EOF # 重启容器刷新 Prisma 缓存 docker-compose restart app
🏗️ 最终架构
中国服务器 (cbiu.fun) 美国 VPS (216.40.86.126) ┌──────────────────────────┐ ┌──────────────────┐ │ Docker Container │ │ │ │ ┌────────────────────┐ │ │ V2Ray Server │ │ │ Next.js App │ │ │ (port 10086) │ │ │ ↓ │ │ │ VMess+WebSocket │ │ │ proxychains4 │──┼─Host──┼─>│ ↓ │ │ └────────────────────┘ │ Mode │ Google APIs │ │ │ │ │ │ V2Ray Client (Host) │ └──────────────────┘ │ HTTP Proxy :10808 │ │ │ │ MySQL Database │ │ IP: 172.18.0.1:3306 │ │ (Docker bridge network) │ └──────────────────────────┘
网络流程:
- Next.js App 通过 proxychains 启动
- 对 Google API 的请求 → proxychains → V2Ray Client (127.0.0.1:10808)
- V2Ray Client → V2Ray Server (美国) → Google
- 对数据库的请求 → 被 localnet 排除 → 直接访问 172.18.0.1:3306
📝 关键配置文件
Dockerfile
# 安装 proxychains RUN apk add --no-cache proxychains-ng # 复制配置到正确路径 RUN mkdir -p /etc/proxychains COPY proxychains.conf /etc/proxychains/proxychains.conf # 使用 proxychains 包装启动命令 CMD ["proxychains4", "-q", "node", "server.js"]
docker-compose.yml
services: app: network_mode: "host" environment: - DATABASE_URL=mysql://root:123456@172.18.0.1:3306/cbiu_webside - AUTH_TRUST_HOST=true - AUTH_URL=https://cbiu.fun - HTTP_PROXY=http://127.0.0.1:10808 - HTTPS_PROXY=http://127.0.0.1:10808 - NO_PROXY=localhost,127.0.0.1,db,172.17.0.1,172.18.0.1,172.17.0.0/16,172.18.0.0/16
🔧 维护命令
V2Ray 管理
# 检查 V2Ray 客户端状态 ps aux | grep v2ray # 查看日志 tail -f /var/log/v2ray.log # 重启 V2Ray 客户端 pkill v2ray nohup /usr/local/v2ray/v2ray run -c /usr/local/v2ray/config.json > /var/log/v2ray.log 2>&1 & # 测试代理 curl -x http://127.0.0.1:10808 https://www.google.com
数据库管理
# 查看表结构 docker-compose exec db mysql -uroot -p123456 cbiu_webside -e "SHOW TABLES;" docker-compose exec db mysql -uroot -p123456 cbiu_webside -e "DESCRIBE users;" # 查看用户 docker-compose exec db mysql -uroot -p123456 cbiu_webside -e "SELECT id, name, email, role FROM users;"
应用调试
# 查看日志 docker-compose logs -f app # 检查容器内配置 docker exec cbiu-website cat /etc/proxychains/proxychains.conf docker exec cbiu-website env | grep -E 'DATABASE|PROXY' # 测试数据库连接 docker exec cbiu-website sh -c "nc -zv 172.18.0.1 3306"
💡 经验总结
1. GFW 绕过
- ❌ 简单 HTTP 代理容易被 DPI 检测
- ✅ VMess + WebSocket 加密协议成功绕过
2. Proxychains 配置
- ⚠️ Alpine Linux 的默认路径是
/etc/proxychains/proxychains.conf - ✅ 必须配置 localnet 排除内网流量
- ✅ Docker 网络段(172.17.0.0/16, 172.18.0.0/16)也要排除
3. Docker 网络
- ⚠️ Host network mode 不能直接访问 bridge 网络容器的 localhost
- ✅ 使用 Docker 网络网关 IP(如 172.18.0.1)
4. NextAuth Schema
- ✅ 生产数据库必须包含:accounts, sessions, verification_tokens
- ✅ users 表必须有:name, email_verified, image
- ⚠️ username 和 password_hash 必须为可选(Google OAuth 不提供)
5. Prisma 客户端缓存
- ⚠️ Schema 修改后需要重启容器刷新 Prisma 客户端
✅ 验证清单
- V2Ray 客户端运行正常
- 代理可以访问 Google (
curl -x http://127.0.0.1:10808 https://www.google.com) - Proxychains 配置路径正确 (
/etc/proxychains/proxychains.conf) - 数据库连接正常(应用无错误日志)
- 所有 NextAuth 表已创建
- users 表 schema 完整
- Google OAuth 登录流程成功
- 用户数据正确保存到数据库
📚 参考资料
Comments(0)
Please login to comment
No comments yet. Be the first to comment!