diff --git a/env-example/.env.development.example b/env-example/.env.development.example index 6bb8da7b..470eb50c 100644 --- a/env-example/.env.development.example +++ b/env-example/.env.development.example @@ -1,6 +1,9 @@ # 当前环境: development NEXT_PUBLIC_APP_ENV=development +# NextAuth v4 —— OAuth callback base URL(dev 本机) +NEXTAUTH_URL=http://localhost:3000 + # 后端 API 基础 URL(开发环境) NEXT_PUBLIC_API_BASE_URL=http://172.16.48.49:3002 @@ -12,9 +15,6 @@ NEXT_PUBLIC_API_CONNECT_TIMEOUT=30000 NEXT_PUBLIC_API_RECEIVE_TIMEOUT=60000 NEXT_PUBLIC_API_SEND_TIMEOUT=30000 -# next-auth v4(Auth.js) -AUTH_SECRET=+0ttNDq3+OCNTrdcokOR4GZo761PiVJIGZOqUsnFOIg= - # 第三方 OAuth AUTH_GOOGLE_ID=351948560061-isubggf6eahfii9n0stpf2qu3haralro.apps.googleusercontent.com AUTH_GOOGLE_SECRET=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 diff --git a/env-example/.env.local.example b/env-example/.env.local.example index be318c00..d927524f 100644 --- a/env-example/.env.local.example +++ b/env-example/.env.local.example @@ -1,13 +1,14 @@ NEXT_PUBLIC_APP_ENV=test + +# NextAuth v4 —— OAuth callback **公**网 base URL(**必**须与**公**网域名**一**致) +NEXTAUTH_URL=https://frontend-test.banlv-ai.com +NEXTAUTH_URL_INTERNAL=http://localhost:3000 NEXT_PUBLIC_API_BASE_URL=https://api.cozsweet.com NEXT_PUBLIC_WS_BASE_URL=wss://api.cozsweet.com NEXT_PUBLIC_API_CONNECT_TIMEOUT=30000 NEXT_PUBLIC_API_RECEIVE_TIMEOUT=60000 NEXT_PUBLIC_API_SEND_TIMEOUT=30000 -# next-auth v4(Auth.js) -AUTH_SECRET=+0ttNDq3+OCNTrdcokOR4GZo761PiVJIGZOqUsnFOIg= - # 第三方 OAuth AUTH_GOOGLE_ID=351948560061-isubggf6eahfii9n0stpf2qu3haralro.apps.googleusercontent.com AUTH_GOOGLE_SECRET=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 diff --git a/env-example/.env.production.example b/env-example/.env.production.example index 9d97ee66..a5d5a120 100644 --- a/env-example/.env.production.example +++ b/env-example/.env.production.example @@ -1,6 +1,10 @@ # 当前环境: production NEXT_PUBLIC_APP_ENV=production +# NextAuth v4 —— OAuth callback **公**网 base URL(**必**须与**公**网域名**一**致) +NEXTAUTH_URL=https://cozsweet.com +NEXTAUTH_URL_INTERNAL=http://localhost:3000 + # 后端 API 基础 URL(生产环境) NEXT_PUBLIC_API_BASE_URL=https://api.cozsweet.com @@ -12,9 +16,6 @@ NEXT_PUBLIC_API_CONNECT_TIMEOUT=30000 NEXT_PUBLIC_API_RECEIVE_TIMEOUT=60000 NEXT_PUBLIC_API_SEND_TIMEOUT=30000 -# next-auth v4(Auth.js) -AUTH_SECRET=+0ttNDq3+OCNTrdcokOR4GZo761PiVJIGZOqUsnFOIg= - # 第三方 OAuth AUTH_GOOGLE_ID=351948560061-isubggf6eahfii9n0stpf2qu3haralro.apps.googleusercontent.com AUTH_GOOGLE_SECRET=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 diff --git a/scripts/deploy/nginx-frontend-test.conf.example b/scripts/deploy/nginx-frontend-test.conf.example new file mode 100644 index 00000000..60ce9ddc --- /dev/null +++ b/scripts/deploy/nginx-frontend-test.conf.example @@ -0,0 +1,99 @@ +# Nginx 反向代理配置模板(test 环境) +# +# 用途:frontend-test.banlv-ai.com → http://localhost:3000 (Next.js) +# +# **关键**:转发 `Host` / `X-Forwarded-Host` / `X-Forwarded-Proto` 请求头 +# —— NextAuth v4 靠这些**算**对 OAuth callback 的 `redirect_uri` +# —— **不**传的话 Next.js 看**到** `Host: localhost:3000`, +# `redirect_uri = http://localhost:3000/api/auth/callback/facebook` +# → Facebook 拒**绝**(**不**在白名单)→ 跳 error?error=OAuthSignin +# +# 部署步骤(**手**动,**不**会**自**动部署): +# 1. cp scripts/deploy/nginx-frontend-test.conf.example /etc/nginx/sites-available/frontend-test.banlv-ai.com +# 2. ln -s /etc/nginx/sites-available/frontend-test.banlv-ai.com /etc/nginx/sites-enabled/ +# 3. certbot --nginx -d frontend-test.banlv-ai.com # 如果**还**没**装** SSL +# 4. nginx -t && nginx -s reload + +server { + listen 80; + listen [::]:80; + server_name frontend-test.banlv-ai.com; + + # **强**制 HTTPS(**可**选 —— 如**果**已经**有** certbot,**让** certbot **自**动**加** 301) + # return 301 https://$host$request_uri; + + # **可**选:acme-challenge 给 certbot 验证**用** + # location /.well-known/acme-challenge/ { + # root /var/www/html; + # } + + location / { + proxy_pass http://localhost:3000; + proxy_http_version 1.1; + + # **核心** —— 转发**公**网 host / protocol 给 Next.js + # NextAuth v4 **优**先**级**: + # 1. NEXTAUTH_URL env + # 2. Host 头(nginx **不**转发 = Next.js 看**到** localhost:3000)❌ + # 3. X-Forwarded-Host 头 ← **这**行**关**键,**不**传就 GG + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + # WebSocket 支持(Next.js HMR + 业务 WS) + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # 超时 + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +} + +# HTTPS server block(certbot 会**自**动**生**成) +# 如**果** certbot **没**自**动**加,**手**动**复**制**下**面 +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + server_name frontend-test.banlv-ai.com; + + ssl_certificate /etc/letsencrypt/live/frontend-test.banlv-ai.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/frontend-test.banlv-ai.com/privkey.pem; + + # SSL 配置(**参**考 Mozilla Intermediate) + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; + ssl_prefer_server_ciphers off; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 1d; + ssl_session_tickets off; + + # HSTS + add_header Strict-Transport-Security "max-age=63072000" always; + add_header X-Frame-Options SAMEORIGIN; + add_header X-Content-Type-Options nosniff; + + location / { + proxy_pass http://localhost:3000; + proxy_http_version 1.1; + + # **核心** —— 转发**公**网 host / protocol(**与** HTTP block **同**) + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + } +}