Files
claude-relay-service/scripts/test-openai-refresh.js
shaw 812e98355f feat: 实现 OpenAI token 自动刷新功能并优化账户管理界面
主要更改:
1. OpenAI Token 自动刷新
   - 实现 refreshAccessToken 函数,支持 OAuth 2.0 refresh_token grant type
   - 使用 Codex CLI 官方 CLIENT_ID (app_EMoamEEZ73f0CkXaXp7hrann)
   - 支持 SOCKS5 和 HTTP/HTTPS 代理
   - 自动更新 access token、id token 和 refresh token

2. 账户管理界面优化
   - 移除手动刷新 token 按钮(桌面端和移动端)
   - 保留后端自动刷新机制
   - 优化代码结构,删除不再需要的函数和变量

3. 测试和文档
   - 添加 test-openai-refresh.js 测试脚本
   - 创建详细的实现文档

技术细节:
- Token 端点: https://auth.openai.com/oauth/token
- 默认有效期: 1小时
- 加密存储: AES-256-CBC

所有平台现在都支持自动 token 刷新:
 Claude - OAuth 自动刷新
 Gemini - Google OAuth2 自动刷新
 OpenAI - OAuth 自动刷新(新实现)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-15 16:56:44 +08:00

103 lines
3.9 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* OpenAI Token 刷新功能测试脚本
* 用于测试 openaiAccountService 的 token 刷新功能
*/
const openaiAccountService = require('../src/services/openaiAccountService')
const logger = require('../src/utils/logger')
// 测试配置(可以通过环境变量或命令行参数传入)
const TEST_REFRESH_TOKEN = process.env.OPENAI_REFRESH_TOKEN || process.argv[2]
async function testRefreshToken() {
if (!TEST_REFRESH_TOKEN) {
console.error('❌ 请提供 refresh token 作为参数或设置环境变量 OPENAI_REFRESH_TOKEN')
console.log('使用方法:')
console.log(' node scripts/test-openai-refresh.js <refresh_token>')
console.log(' 或')
console.log(' OPENAI_REFRESH_TOKEN=<token> node scripts/test-openai-refresh.js')
process.exit(1)
}
console.log('🔄 开始测试 OpenAI token 刷新功能...\n')
try {
// 测试不带代理的刷新
console.log('1⃣ 测试直接刷新(无代理)...')
const result = await openaiAccountService.refreshAccessToken(TEST_REFRESH_TOKEN)
console.log('✅ 刷新成功!')
console.log(' Access Token:', result.access_token ? result.access_token.substring(0, 30) + '...' : 'N/A')
console.log(' ID Token:', result.id_token ? result.id_token.substring(0, 30) + '...' : 'N/A')
console.log(' Refresh Token:', result.refresh_token ? result.refresh_token.substring(0, 30) + '...' : 'N/A')
console.log(' 有效期:', result.expires_in, '秒')
console.log(' 过期时间:', new Date(result.expiry_date).toLocaleString())
// 如果返回了新的 refresh token
if (result.refresh_token && result.refresh_token !== TEST_REFRESH_TOKEN) {
console.log('\n⚠ 注意:收到了新的 refresh token请保存以供后续使用')
}
// 测试带代理的刷新(如果配置了代理)
if (process.env.PROXY_HOST && process.env.PROXY_PORT) {
console.log('\n2⃣ 测试通过代理刷新...')
const proxy = {
type: process.env.PROXY_TYPE || 'http',
host: process.env.PROXY_HOST,
port: parseInt(process.env.PROXY_PORT),
username: process.env.PROXY_USERNAME,
password: process.env.PROXY_PASSWORD
}
console.log(' 代理配置:', `${proxy.type}://${proxy.host}:${proxy.port}`)
const proxyResult = await openaiAccountService.refreshAccessToken(
result.refresh_token || TEST_REFRESH_TOKEN,
proxy
)
console.log('✅ 通过代理刷新成功!')
console.log(' Access Token:', proxyResult.access_token ? proxyResult.access_token.substring(0, 30) + '...' : 'N/A')
}
// 测试完整的账户刷新流程如果提供了账户ID
if (process.env.OPENAI_ACCOUNT_ID) {
console.log('\n3⃣ 测试账户刷新流程...')
console.log(' 账户ID:', process.env.OPENAI_ACCOUNT_ID)
try {
const account = await openaiAccountService.getAccount(process.env.OPENAI_ACCOUNT_ID)
if (account) {
console.log(' 账户名称:', account.name)
console.log(' 当前过期时间:', account.expiresAt)
const refreshResult = await openaiAccountService.refreshAccountToken(process.env.OPENAI_ACCOUNT_ID)
console.log('✅ 账户 token 刷新成功!')
console.log(' 新的过期时间:', new Date(refreshResult.expiry_date).toLocaleString())
}
} catch (error) {
console.log('⚠️ 账户刷新测试失败:', error.message)
}
}
console.log('\n✅ 所有测试完成!')
} catch (error) {
console.error('\n❌ 测试失败:', error.message)
if (error.response) {
console.error('响应状态:', error.response.status)
console.error('响应数据:', error.response.data)
}
process.exit(1)
}
}
// 运行测试
testRefreshToken().then(() => {
process.exit(0)
}).catch((error) => {
console.error('Unexpected error:', error)
process.exit(1)
})