Skip to content

OpenAI 账号导出 JSON 无法被“导入 OpenAI 账号”重新导入 #86

Description

@songsongQAQ

问题描述

ATM 的 OpenAI 账号“导出账号”功能导出的 JSON,无法被同一个应用里的“导入 OpenAI 账号”功能重新导入。

我是在一台 Mac 上通过 ATM 导出 OpenAI 账号 JSON,然后在另一台 Mac 上用 ATM 导入。导入时提示:

文件内容为空或没有有效的账号数据

但实际上文件内容是正常的,且账号数据完整。


环境信息

  • ATM 版本:v1.9.11
  • 平台:macOS
  • 迁移方式:从另一台 Mac 的 ATM 导出 OpenAI 账号 JSON,再导入到当前 Mac 的 ATM

复现步骤

  1. 在 ATM 的 OpenAI 账号页面点击“导出账号”
  2. 得到一个 JSON 文件
  3. 在另一台 Mac 的 ATM 中打开“导入 OpenAI 账号”
  4. 选择刚才导出的 JSON 文件
  5. 出现错误:文件内容为空或没有有效的账号数据

实际结果

导出的 JSON 不能被导入器识别,导入失败。


预期结果

同一个 ATM 导出的 OpenAI 账号 JSON,应该可以被 ATM 自己重新导入。


问题分析

我查看了项目源码,发现 OpenAI 账号的导出格式和导入格式没有对齐。

1. 导出逻辑

OpenAI 页面导出时,直接把内存中的 accounts.value 原样 JSON.stringify 导出:

文件位置:

src/components/platform/OpenAIAccountManager.vue

相关逻辑:

const dataStr = JSON.stringify(accounts.value, null, 2)

这意味着导出的其实是 ATM 当前使用的内部账号结构,而不是导入器要求的 CPA 格式。

导出的实际结构类似这样:

[
  {
    "id": "...",
    "email": "...",
    "account_type": "oauth",
    "token": {
      "access_token": "...",
      "refresh_token": "...",
      "id_token": "..."
    },
    "chatgpt_account_id": "...",
    "organization_id": "...",
    "openai_auth_json": "..."
  }
]

这里可以看到,token 相关字段在嵌套对象 token 下面,而不是顶层字段。

2. 导入逻辑

导入弹窗只接受以下几种格式:

  • Refresh Token 字符串数组
  • 顶层带 access_token 的 CPA 单对象
  • 顶层带 access_token 的 CPA 对象数组

文件位置:

src/components/openai/OpenAIImportAccountsDialog.vue

相关判断逻辑:

const isCpaObject = (item) => {
  return item && typeof item === 'object' && typeof item.access_token === 'string'
}

也就是说,导入器判断一个对象是否为有效账号时,只检查对象顶层是否存在 access_token。

但 ATM 导出的 JSON 结构里,access_token 实际在:

token.access_token

因此导入器不会把 ATM 自己导出的账号对象识别成有效账号数据,最终报出:

文件内容为空或没有有效的账号数据


结论

这是一个 OpenAI 账号导出格式与导入格式不兼容 的问题。

也就是说:

  • 导出器导出的是 ATM 的内部账号结构
  • 导入器只接受 RT 数组或 CPA 顶层 token 结构
  • 导出和导入不是同一种格式
  • 所以“从 ATM 导出,再导回 ATM”这条路径当前是失效的

影响

这个问题会导致以下场景无法正常工作:

  • 用户从一台 Mac 的 ATM 导出 OpenAI 账号后,无法在另一台 Mac 的 ATM 中直接导入
  • 用户误以为导出的 JSON 已损坏
  • 实际上文件内容是正常的,只是格式与导入器预期不匹配

建议修复方向

建议至少支持以下任意一种方案:

  1. 修改导出逻辑
    让“导出账号”直接输出导入器兼容的 CPA 格式,而不是内部账号结构

  2. 修改导入逻辑
    让导入器兼容 ATM 当前导出的内部账号结构,支持从以下路径读取 token:

    • token.access_token
    • token.refresh_token
    • token.id_token
  3. 最佳方案
    同时兼容两种格式:

    • 现有 CPA 格式 / RT 数组
    • ATM 自身导出的内部账号结构

这样用户无论导入哪种来源的文件,都能正常完成导入。


补充说明

我已经在本地验证过:

  • ATM 导出的原始 JSON 文件本身是有效的
  • 只要把它转换成导入器期望的 CPA 格式,就可以成功导入
  • 说明问题不在文件内容损坏,而在于导出器和导入器格式定义不一致

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions