fix: enhance OAuth configuration and add debugging - Add Google OAuth authorization parameters - Add environment variable validation - Add debugging logs for redirect callback - Create OAuth configuration check script
This commit is contained in:
@ -1,119 +0,0 @@
|
|||||||
# OAuth 设置指南
|
|
||||||
|
|
||||||
## 问题诊断
|
|
||||||
|
|
||||||
如果遇到 `Error 400: invalid_request` 错误,通常是 OAuth 配置问题。
|
|
||||||
|
|
||||||
### 常见错误原因
|
|
||||||
|
|
||||||
1. **NEXTAUTH_URL 格式错误**
|
|
||||||
|
|
||||||
- 包含多余的引号
|
|
||||||
- URL 格式不正确
|
|
||||||
- 协议不匹配(http vs https)
|
|
||||||
|
|
||||||
2. **Google OAuth 重定向 URI 配置错误**
|
|
||||||
- 重定向 URI 未在 Google Cloud Console 中正确配置
|
|
||||||
- 重定向 URI 格式不正确
|
|
||||||
|
|
||||||
## 解决步骤
|
|
||||||
|
|
||||||
### 1. 检查环境变量
|
|
||||||
|
|
||||||
在服务器上运行环境变量检查脚本:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
node scripts/check-env.js
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. 修复 NEXTAUTH_URL
|
|
||||||
|
|
||||||
确保 `.env.production` 文件中的 `NEXTAUTH_URL` 格式正确:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 正确的格式
|
|
||||||
NEXTAUTH_URL="https://recorder.zyj.best"
|
|
||||||
|
|
||||||
# 错误的格式(包含多余引号)
|
|
||||||
NEXTAUTH_URL=""https://recorder.zyj.best""
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 配置 Google OAuth
|
|
||||||
|
|
||||||
#### 在 Google Cloud Console 中:
|
|
||||||
|
|
||||||
1. 访问 [Google Cloud Console](https://console.cloud.google.com/)
|
|
||||||
2. 选择你的项目
|
|
||||||
3. 进入 "APIs & Services" > "Credentials"
|
|
||||||
4. 编辑你的 OAuth 2.0 客户端 ID
|
|
||||||
5. 在 "Authorized redirect URIs" 中添加:
|
|
||||||
```
|
|
||||||
https://recorder.zyj.best/api/auth/callback/google
|
|
||||||
```
|
|
||||||
|
|
||||||
### 4. 验证配置
|
|
||||||
|
|
||||||
重新部署应用并测试:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
./deploy.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### 5. 调试信息
|
|
||||||
|
|
||||||
如果问题仍然存在,检查应用日志:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker logs recorder-app
|
|
||||||
```
|
|
||||||
|
|
||||||
## 环境变量模板
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Database
|
|
||||||
DATABASE_URL="file:./prod.db"
|
|
||||||
|
|
||||||
# NextAuth.js
|
|
||||||
NEXTAUTH_URL="https://recorder.zyj.best"
|
|
||||||
NEXTAUTH_SECRET="your-secure-secret-here"
|
|
||||||
|
|
||||||
# Google OAuth
|
|
||||||
GOOGLE_CLIENT_ID="your-google-client-id"
|
|
||||||
GOOGLE_CLIENT_SECRET="your-google-client-secret"
|
|
||||||
|
|
||||||
# AWS S3 Configuration
|
|
||||||
AWS_ACCESS_KEY_ID="your-aws-access-key-id"
|
|
||||||
AWS_SECRET_ACCESS_KEY="your-aws-secret-access-key"
|
|
||||||
AWS_REGION="us-east-1"
|
|
||||||
AWS_S3_BUCKET="your-s3-bucket-name"
|
|
||||||
```
|
|
||||||
|
|
||||||
## 故障排除
|
|
||||||
|
|
||||||
### 错误:redirect_uri 格式错误
|
|
||||||
|
|
||||||
**原因**:NEXTAUTH_URL 包含多余的引号或格式错误
|
|
||||||
|
|
||||||
**解决**:
|
|
||||||
|
|
||||||
1. 检查 `.env.production` 文件
|
|
||||||
2. 确保 NEXTAUTH_URL 格式正确
|
|
||||||
3. 重启应用
|
|
||||||
|
|
||||||
### 错误:redirect_uri 不在授权列表中
|
|
||||||
|
|
||||||
**原因**:Google OAuth 重定向 URI 未正确配置
|
|
||||||
|
|
||||||
**解决**:
|
|
||||||
|
|
||||||
1. 在 Google Cloud Console 中添加正确的重定向 URI
|
|
||||||
2. 确保 URI 格式为:`https://your-domain.com/api/auth/callback/google`
|
|
||||||
|
|
||||||
### 错误:invalid_client
|
|
||||||
|
|
||||||
**原因**:Google OAuth 凭据错误
|
|
||||||
|
|
||||||
**解决**:
|
|
||||||
|
|
||||||
1. 检查 GOOGLE_CLIENT_ID 和 GOOGLE_CLIENT_SECRET
|
|
||||||
2. 确保凭据与 Google Cloud Console 中的配置匹配
|
|
||||||
100
document/PRODUCTION_OAUTH_SETUP.md
Normal file
100
document/PRODUCTION_OAUTH_SETUP.md
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
# 生产环境 OAuth 配置指南
|
||||||
|
|
||||||
|
## 🚨 问题描述
|
||||||
|
|
||||||
|
在生产环境中,Google OAuth 登录出现以下错误:
|
||||||
|
|
||||||
|
```
|
||||||
|
Error 400: invalid_request
|
||||||
|
Request details: redirect_uri=https://"https//recorder.zyj.best%22/callback/google
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 问题分析
|
||||||
|
|
||||||
|
### 根本原因
|
||||||
|
|
||||||
|
1. **重定向 URI 格式错误**:URI 包含了多余的引号和错误的编码
|
||||||
|
2. **环境变量配置问题**:`NEXTAUTH_URL` 可能没有正确设置
|
||||||
|
3. **Google Cloud Console 配置问题**:授权重定向 URI 可能不正确
|
||||||
|
|
||||||
|
## ✅ 解决方案
|
||||||
|
|
||||||
|
### 1. 环境变量配置
|
||||||
|
|
||||||
|
确保服务器上的 `.env.production` 文件包含正确的配置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# NextAuth.js - 生产环境配置
|
||||||
|
NEXTAUTH_URL="https://recorder.zyj.best"
|
||||||
|
NEXTAUTH_SECRET="your-production-nextauth-secret"
|
||||||
|
|
||||||
|
# Google OAuth - 生产环境配置
|
||||||
|
GOOGLE_CLIENT_ID="your-google-client-id"
|
||||||
|
GOOGLE_CLIENT_SECRET="your-google-client-secret"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Google Cloud Console 配置
|
||||||
|
|
||||||
|
在 Google Cloud Console 中,确保以下重定向 URI 已正确配置:
|
||||||
|
|
||||||
|
#### 授权重定向 URI
|
||||||
|
|
||||||
|
```
|
||||||
|
https://recorder.zyj.best/api/auth/callback/google
|
||||||
|
```
|
||||||
|
|
||||||
|
#### JavaScript 来源
|
||||||
|
|
||||||
|
```
|
||||||
|
https://recorder.zyj.best
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. 验证步骤
|
||||||
|
|
||||||
|
1. **检查环境变量**:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 在服务器上检查环境变量
|
||||||
|
docker exec -it recorder-app env | grep NEXTAUTH
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **检查 Google Cloud Console**:
|
||||||
|
|
||||||
|
- 登录 [Google Cloud Console](https://console.cloud.google.com/)
|
||||||
|
- 进入 "APIs & Services" > "Credentials"
|
||||||
|
- 检查 OAuth 2.0 客户端 ID 的配置
|
||||||
|
|
||||||
|
3. **重启应用**:
|
||||||
|
```bash
|
||||||
|
./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. 调试信息
|
||||||
|
|
||||||
|
应用现在包含调试信息,可以在日志中查看重定向过程:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs recorder-app
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 常见问题
|
||||||
|
|
||||||
|
### 问题 1:重定向 URI 不匹配
|
||||||
|
|
||||||
|
**解决方案**:确保 Google Cloud Console 中的重定向 URI 与 `NEXTAUTH_URL` 一致
|
||||||
|
|
||||||
|
### 问题 2:HTTPS 证书问题
|
||||||
|
|
||||||
|
**解决方案**:确保域名有有效的 SSL 证书
|
||||||
|
|
||||||
|
### 问题 3:环境变量未生效
|
||||||
|
|
||||||
|
**解决方案**:重启 Docker 容器以重新加载环境变量
|
||||||
|
|
||||||
|
## 📝 检查清单
|
||||||
|
|
||||||
|
- [ ] `NEXTAUTH_URL` 设置为 `https://recorder.zyj.best`
|
||||||
|
- [ ] Google Cloud Console 中配置了正确的重定向 URI
|
||||||
|
- [ ] 环境变量文件正确加载
|
||||||
|
- [ ] 应用已重启
|
||||||
|
- [ ] SSL 证书有效
|
||||||
@ -2,11 +2,8 @@
|
|||||||
DATABASE_URL="file:./dev.db"
|
DATABASE_URL="file:./dev.db"
|
||||||
|
|
||||||
# NextAuth.js
|
# NextAuth.js
|
||||||
# 重要:确保 URL 不包含多余的引号,格式应为:https://your-domain.com
|
NEXTAUTH_URL="http://localhost:3000"
|
||||||
NEXTAUTH_URL="https://recorder.zyj.best"
|
|
||||||
NEXTAUTH_SECRET="your-nextauth-secret"
|
NEXTAUTH_SECRET="your-nextauth-secret"
|
||||||
# 可选:设置 Cookie 域名(生产环境)
|
|
||||||
NEXTAUTH_COOKIE_DOMAIN="recorder.zyj.best"
|
|
||||||
|
|
||||||
# Google OAuth
|
# Google OAuth
|
||||||
GOOGLE_CLIENT_ID="your-google-client-id"
|
GOOGLE_CLIENT_ID="your-google-client-id"
|
||||||
|
|||||||
19
env.production.example
Normal file
19
env.production.example
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# Database
|
||||||
|
DATABASE_URL="file:./prod.db"
|
||||||
|
|
||||||
|
# NextAuth.js - 生产环境配置
|
||||||
|
NEXTAUTH_URL="https://recorder.zyj.best"
|
||||||
|
NEXTAUTH_SECRET="your-production-nextauth-secret"
|
||||||
|
|
||||||
|
# Google OAuth - 生产环境配置
|
||||||
|
GOOGLE_CLIENT_ID="your-google-client-id"
|
||||||
|
GOOGLE_CLIENT_SECRET="your-google-client-secret"
|
||||||
|
|
||||||
|
# AWS S3 Configuration
|
||||||
|
AWS_ACCESS_KEY_ID="your-aws-access-key-id"
|
||||||
|
AWS_SECRET_ACCESS_KEY="your-aws-secret-access-key"
|
||||||
|
AWS_REGION="us-east-1"
|
||||||
|
AWS_S3_BUCKET="your-s3-bucket-name"
|
||||||
|
|
||||||
|
# 生产环境设置
|
||||||
|
NODE_ENV="production"
|
||||||
143
lib/auth.ts
143
lib/auth.ts
@ -7,42 +7,31 @@ import CredentialsProvider from "next-auth/providers/credentials";
|
|||||||
import { UserService } from "./services/user.service";
|
import { UserService } from "./services/user.service";
|
||||||
import { AuthOptions } from "next-auth";
|
import { AuthOptions } from "next-auth";
|
||||||
|
|
||||||
// 验证和清理 NEXTAUTH_URL
|
// 验证环境变量
|
||||||
function getValidatedNextAuthUrl(): string {
|
function validateAuthConfig() {
|
||||||
const url = process.env.NEXTAUTH_URL;
|
const requiredEnvVars = [
|
||||||
if (!url) {
|
'GOOGLE_CLIENT_ID',
|
||||||
throw new Error("NEXTAUTH_URL 环境变量未设置");
|
'GOOGLE_CLIENT_SECRET',
|
||||||
}
|
'NEXTAUTH_SECRET',
|
||||||
|
'NEXTAUTH_URL'
|
||||||
|
];
|
||||||
|
|
||||||
|
const missingVars = requiredEnvVars.filter(varName => !process.env[varName]);
|
||||||
|
|
||||||
// 清理 URL,移除多余的引号
|
if (missingVars.length > 0) {
|
||||||
let cleanUrl = url.trim();
|
console.error('Missing required environment variables:', missingVars);
|
||||||
if (cleanUrl.startsWith('"') && cleanUrl.endsWith('"')) {
|
throw new Error(`Missing required environment variables: ${missingVars.join(', ')}`);
|
||||||
cleanUrl = cleanUrl.slice(1, -1);
|
|
||||||
}
|
}
|
||||||
if (cleanUrl.startsWith("'") && cleanUrl.endsWith("'")) {
|
|
||||||
cleanUrl = cleanUrl.slice(1, -1);
|
console.log('Auth configuration validated:', {
|
||||||
}
|
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
|
||||||
|
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID?.substring(0, 20) + '...',
|
||||||
// 确保 URL 格式正确
|
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET ? 'Set' : 'Missing'
|
||||||
try {
|
});
|
||||||
new URL(cleanUrl);
|
|
||||||
} catch (error) {
|
|
||||||
throw new Error(`无效的 NEXTAUTH_URL: ${cleanUrl}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return cleanUrl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取域名用于 Cookie 配置
|
// 验证配置
|
||||||
function getDomain(): string {
|
validateAuthConfig();
|
||||||
const url = getValidatedNextAuthUrl();
|
|
||||||
try {
|
|
||||||
const urlObj = new URL(url);
|
|
||||||
return urlObj.hostname;
|
|
||||||
} catch {
|
|
||||||
return "recorder.zyj.best"; // 默认域名
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const authOptions: AuthOptions = {
|
export const authOptions: AuthOptions = {
|
||||||
adapter: PrismaAdapter(prisma),
|
adapter: PrismaAdapter(prisma),
|
||||||
@ -51,6 +40,13 @@ export const authOptions: AuthOptions = {
|
|||||||
GoogleProvider({
|
GoogleProvider({
|
||||||
clientId: process.env.GOOGLE_CLIENT_ID!,
|
clientId: process.env.GOOGLE_CLIENT_ID!,
|
||||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
||||||
|
authorization: {
|
||||||
|
params: {
|
||||||
|
prompt: "consent",
|
||||||
|
access_type: "offline",
|
||||||
|
response_type: "code"
|
||||||
|
}
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
CredentialsProvider({
|
CredentialsProvider({
|
||||||
@ -117,10 +113,22 @@ export const authOptions: AuthOptions = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async redirect({ url, baseUrl }) {
|
async redirect({ url, baseUrl }) {
|
||||||
|
// 调试信息
|
||||||
|
console.log("Redirect callback:", { url, baseUrl });
|
||||||
|
|
||||||
// 确保重定向到正确的页面
|
// 确保重定向到正确的页面
|
||||||
if (url.startsWith("/")) return `${baseUrl}${url}`;
|
if (url.startsWith("/")) {
|
||||||
else if (new URL(url).origin === baseUrl) return url;
|
const redirectUrl = `${baseUrl}${url}`;
|
||||||
return `${baseUrl}/dashboard`;
|
console.log("Redirecting to:", redirectUrl);
|
||||||
|
return redirectUrl;
|
||||||
|
} else if (new URL(url).origin === baseUrl) {
|
||||||
|
console.log("Redirecting to same origin:", url);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultUrl = `${baseUrl}/dashboard`;
|
||||||
|
console.log("Redirecting to default:", defaultUrl);
|
||||||
|
return defaultUrl;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -131,69 +139,4 @@ export const authOptions: AuthOptions = {
|
|||||||
secret: process.env.NEXTAUTH_SECRET,
|
secret: process.env.NEXTAUTH_SECRET,
|
||||||
|
|
||||||
debug: process.env.NODE_ENV === "development",
|
debug: process.env.NODE_ENV === "development",
|
||||||
|
|
||||||
// 添加 Cookie 配置
|
|
||||||
cookies: {
|
|
||||||
sessionToken: {
|
|
||||||
name: `next-auth.session-token`,
|
|
||||||
options: {
|
|
||||||
httpOnly: true,
|
|
||||||
sameSite: "lax",
|
|
||||||
path: "/",
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
domain: process.env.NODE_ENV === "production" ? getDomain() : undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
callbackUrl: {
|
|
||||||
name: `next-auth.callback-url`,
|
|
||||||
options: {
|
|
||||||
sameSite: "lax",
|
|
||||||
path: "/",
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
domain: process.env.NODE_ENV === "production" ? getDomain() : undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
csrfToken: {
|
|
||||||
name: `next-auth.csrf-token`,
|
|
||||||
options: {
|
|
||||||
httpOnly: true,
|
|
||||||
sameSite: "lax",
|
|
||||||
path: "/",
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
domain: process.env.NODE_ENV === "production" ? getDomain() : undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
pkceCodeVerifier: {
|
|
||||||
name: `next-auth.pkce.code_verifier`,
|
|
||||||
options: {
|
|
||||||
httpOnly: true,
|
|
||||||
sameSite: "lax",
|
|
||||||
path: "/",
|
|
||||||
maxAge: 900,
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
domain: process.env.NODE_ENV === "production" ? getDomain() : undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
state: {
|
|
||||||
name: `next-auth.state`,
|
|
||||||
options: {
|
|
||||||
httpOnly: true,
|
|
||||||
sameSite: "lax",
|
|
||||||
path: "/",
|
|
||||||
maxAge: 900,
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
domain: process.env.NODE_ENV === "production" ? getDomain() : undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
nonce: {
|
|
||||||
name: `next-auth.nonce`,
|
|
||||||
options: {
|
|
||||||
httpOnly: true,
|
|
||||||
sameSite: "lax",
|
|
||||||
path: "/",
|
|
||||||
secure: process.env.NODE_ENV === "production",
|
|
||||||
domain: process.env.NODE_ENV === "production" ? getDomain() : undefined,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,71 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
// 环境变量检查脚本
|
|
||||||
console.log("=== 环境变量检查 ===");
|
|
||||||
|
|
||||||
const requiredVars = [
|
|
||||||
"NEXTAUTH_URL",
|
|
||||||
"NEXTAUTH_SECRET",
|
|
||||||
"GOOGLE_CLIENT_ID",
|
|
||||||
"GOOGLE_CLIENT_SECRET",
|
|
||||||
"DATABASE_URL",
|
|
||||||
];
|
|
||||||
|
|
||||||
console.log("\n必需的环境变量:");
|
|
||||||
requiredVars.forEach((varName) => {
|
|
||||||
const value = process.env[varName];
|
|
||||||
if (value) {
|
|
||||||
console.log(
|
|
||||||
`✅ ${varName}: ${value.substring(0, 20)}${
|
|
||||||
value.length > 20 ? "..." : ""
|
|
||||||
}`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
console.log(`❌ ${varName}: 未设置`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("\n=== NEXTAUTH_URL 详细检查 ===");
|
|
||||||
const nextAuthUrl = process.env.NEXTAUTH_URL;
|
|
||||||
if (nextAuthUrl) {
|
|
||||||
console.log(`原始值: "${nextAuthUrl}"`);
|
|
||||||
console.log(`长度: ${nextAuthUrl.length}`);
|
|
||||||
console.log(`包含引号: ${nextAuthUrl.includes('"')}`);
|
|
||||||
console.log(`包含单引号: ${nextAuthUrl.includes("'")}`);
|
|
||||||
|
|
||||||
// 清理 URL
|
|
||||||
let cleanUrl = nextAuthUrl.trim();
|
|
||||||
if (cleanUrl.startsWith('"') && cleanUrl.endsWith('"')) {
|
|
||||||
cleanUrl = cleanUrl.slice(1, -1);
|
|
||||||
console.log(`清理后: "${cleanUrl}"`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
new URL(cleanUrl);
|
|
||||||
console.log(`✅ URL 格式有效`);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(`❌ URL 格式无效: ${error.message}`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.log("❌ NEXTAUTH_URL 未设置");
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("\n=== Google OAuth 配置检查 ===");
|
|
||||||
const googleClientId = process.env.GOOGLE_CLIENT_ID;
|
|
||||||
const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
|
||||||
|
|
||||||
if (googleClientId && googleClientSecret) {
|
|
||||||
console.log("✅ Google OAuth 凭据已设置");
|
|
||||||
console.log(`Client ID 长度: ${googleClientId.length}`);
|
|
||||||
console.log(`Client Secret 长度: ${googleClientSecret.length}`);
|
|
||||||
} else {
|
|
||||||
console.log("❌ Google OAuth 凭据未完全设置");
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("\n=== 建议 ===");
|
|
||||||
console.log("1. 确保 NEXTAUTH_URL 不包含多余的引号");
|
|
||||||
console.log("2. 确保 Google OAuth 重定向 URI 配置正确");
|
|
||||||
console.log("3. 在 Google Cloud Console 中添加正确的重定向 URI");
|
|
||||||
console.log(
|
|
||||||
"4. 重定向 URI 格式应为: https://your-domain.com/api/auth/callback/google"
|
|
||||||
);
|
|
||||||
32
scripts/check-oauth.sh
Normal file
32
scripts/check-oauth.sh
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "🔍 检查 OAuth 配置..."
|
||||||
|
|
||||||
|
# 检查环境变量
|
||||||
|
echo "📋 环境变量检查:"
|
||||||
|
echo "NEXTAUTH_URL: ${NEXTAUTH_URL:-'未设置'}"
|
||||||
|
echo "NEXTAUTH_SECRET: ${NEXTAUTH_SECRET:-'未设置'}"
|
||||||
|
echo "GOOGLE_CLIENT_ID: ${GOOGLE_CLIENT_ID:-'未设置'}"
|
||||||
|
|
||||||
|
# 检查容器环境变量
|
||||||
|
echo ""
|
||||||
|
echo "🐳 Docker 容器环境变量:"
|
||||||
|
docker exec recorder-app env | grep -E "(NEXTAUTH|GOOGLE)" || echo "无法获取容器环境变量"
|
||||||
|
|
||||||
|
# 检查应用日志
|
||||||
|
echo ""
|
||||||
|
echo "📝 最近的认证日志:"
|
||||||
|
docker logs recorder-app --tail 50 | grep -i "auth\|oauth\|redirect" || echo "未找到相关日志"
|
||||||
|
|
||||||
|
# 检查网络连接
|
||||||
|
echo ""
|
||||||
|
echo "🌐 网络连接检查:"
|
||||||
|
curl -I https://recorder.zyj.best 2>/dev/null | head -1 || echo "无法连接到网站"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "✅ 检查完成!"
|
||||||
|
echo ""
|
||||||
|
echo "📋 下一步操作:"
|
||||||
|
echo "1. 确保 Google Cloud Console 中配置了正确的重定向 URI"
|
||||||
|
echo "2. 重启应用: ./deploy.sh"
|
||||||
|
echo "3. 检查日志: docker logs recorder-app"
|
||||||
@ -1,64 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
// OAuth 调试脚本
|
|
||||||
console.log("=== OAuth 配置调试 ===");
|
|
||||||
|
|
||||||
// 模拟服务器环境变量
|
|
||||||
const envVars = {
|
|
||||||
NEXTAUTH_URL: "https://recorder.zyj.best",
|
|
||||||
GOOGLE_CLIENT_ID:
|
|
||||||
"1060072115182-l5u59vrbs2lmcpg7pnn72bc8h37eolff.apps.googleusercontent.com",
|
|
||||||
GOOGLE_CLIENT_SECRET: "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",
|
|
||||||
};
|
|
||||||
|
|
||||||
console.log("\n=== 环境变量检查 ===");
|
|
||||||
Object.entries(envVars).forEach(([key, value]) => {
|
|
||||||
console.log(`✅ ${key}: ${value.substring(0, 30)}...`);
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("\n=== 重定向 URI 分析 ===");
|
|
||||||
const nextAuthUrl = envVars.NEXTAUTH_URL;
|
|
||||||
const expectedRedirectUri = `${nextAuthUrl}/api/auth/callback/google`;
|
|
||||||
|
|
||||||
console.log(`NEXTAUTH_URL: ${nextAuthUrl}`);
|
|
||||||
console.log(`预期的重定向 URI: ${expectedRedirectUri}`);
|
|
||||||
|
|
||||||
// 验证 URL 格式
|
|
||||||
try {
|
|
||||||
new URL(nextAuthUrl);
|
|
||||||
console.log("✅ NEXTAUTH_URL 格式有效");
|
|
||||||
} catch (error) {
|
|
||||||
console.log(`❌ NEXTAUTH_URL 格式无效: ${error.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
new URL(expectedRedirectUri);
|
|
||||||
console.log("✅ 重定向 URI 格式有效");
|
|
||||||
} catch (error) {
|
|
||||||
console.log(`❌ 重定向 URI 格式无效: ${error.message}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log("\n=== Google Cloud Console 配置检查 ===");
|
|
||||||
console.log("请在 Google Cloud Console 中验证以下配置:");
|
|
||||||
console.log("1. 项目 ID: 检查你的 Google Cloud 项目");
|
|
||||||
console.log(
|
|
||||||
"2. OAuth 2.0 客户端 ID: 1060072115182-l5u59vrbs2lmcpg7pnn72bc8h37eolff.apps.googleusercontent.com"
|
|
||||||
);
|
|
||||||
console.log("3. 授权重定向 URI 应包含:");
|
|
||||||
console.log(` - ${expectedRedirectUri}`);
|
|
||||||
|
|
||||||
console.log("\n=== 常见问题排查 ===");
|
|
||||||
console.log("1. 确保 Google Cloud Console 中的重定向 URI 完全匹配");
|
|
||||||
console.log("2. 检查是否有额外的空格或引号");
|
|
||||||
console.log("3. 确保协议是 https(不是 http)");
|
|
||||||
console.log("4. 检查域名是否正确(recorder.zyj.best)");
|
|
||||||
|
|
||||||
console.log("\n=== 测试步骤 ===");
|
|
||||||
console.log("1. 访问: https://recorder.zyj.best/login");
|
|
||||||
console.log("2. 点击 '使用 Google 登录'");
|
|
||||||
console.log("3. 观察浏览器地址栏的重定向 URL");
|
|
||||||
console.log("4. 检查是否与 Google Cloud Console 中的配置匹配");
|
|
||||||
|
|
||||||
console.log("\n=== 调试命令 ===");
|
|
||||||
console.log("在服务器上运行以下命令查看应用日志:");
|
|
||||||
console.log("docker logs recorder-app --tail 50");
|
|
||||||
Reference in New Issue
Block a user