Claude iOS 旧 session 卡死:Quantumult X 强制退出登录方案

• 24 分钟阅读 • Default

Claude iOS 卡在 Something went wrong 时,如何用 Quantumult X 强制回到登录页

适用场景:Claude iOS App 打开后一直停在 Something went wrong / Try again,点击重试无效,卸载重装也没有恢复;同时你在 Quantumult X 的网络活动中能看到 Claude App 反复请求 https://claude.ai/api/account?

这个方案不是用来修复代理线路、节点质量或 Claude 服务端故障。它的目标很单一:临时伪造一次“登录态已过期”的响应,让 Claude iOS App 主动退出异常 session,回到登录页。

重要提醒:成功看到登录页后,必须立刻关闭这条 rewrite 规则。不要长期启用。

适合解决什么问题

这个方法适合处理一种比较典型的卡死状态:

  1. Claude iOS App 启动后直接显示 Something went wrongTry again
  2. Try again 没有明显变化。
  3. 切换节点、重启 App、卸载重装后仍然卡住。
  4. Quantumult X 的网络活动里可以看到 Claude App 在请求:
https://claude.ai/api/account?
  1. 你怀疑 App 本地保存的旧登录态、cookie 或 session 已经异常,但 App 没有自动跳回登录页。

如果你的问题是完全无法连接 Claude、TLS 握手失败、节点不支持、DNS 错误、区域不可用,或者根本看不到 Claude App 发起 /api/account 请求,那么这篇方法不一定适用。先把网络和代理本身排查好。

原理说明

Claude iOS App 启动时会访问账号接口,大致是:

https://claude.ai/api/account?

正常情况下,这个接口会根据当前 cookies 判断你是否已经登录。如果旧 session 已经过期或异常,服务端应该返回未登录或 session 失效,然后 App 回到登录页。

但在某些情况下,App 可能持续带着旧的 session cookies 请求接口,却没有顺利完成退出登录流程,于是卡在错误页。

Quantumult X 的 MITM 和 rewrite 可以临时拦截这个请求,直接返回一个伪造的响应:

HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Cache-Control: no-store
Set-Cookie: sessionKey=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/; Domain=claude.ai; Secure; HttpOnly; SameSite=Lax
set-cookie: routingHint=; Expires=Thu, 01 Jan 1970 00:00:00 GMT; Max-Age=0; Path=/; Domain=claude.ai; Secure; HttpOnly; SameSite=Lax

响应 body 返回:

{
  "error": {
    "type": "session_expired",
    "message": "Session expired. Please log in again."
  }
}

这样做的效果是:

  1. Claude App 认为当前登录态已经过期。
  2. sessionKeyroutingHint 被设置为过期。
  3. App 不再继续使用旧 session。
  4. App 回到登录页。

关键点是:Set-Cookie 必须写在响应头里,而不是请求头里。

不要把真实 cookie、sessionKeyroutingHint 发给别人,也不要发到群里让别人帮你看。

操作前准备

你需要准备:

  1. iPhone 上已安装 Quantumult X。
  2. Quantumult X 已经可以正常代理 Claude 相关流量。
  3. Quantumult X 的 MITM 证书已经安装并在 iOS 中信任。
  4. 你能编辑 Quantumult X 配置文件。
  5. 你能在 iPhone 的“文件”App 里找到 Quantumult X 的 Scripts 目录。

如果你平时没有开启 Quantumult X 的 rewrite 功能,记得稍后在 Quantumult X 里打开 rewrite 开关。

第一步:确认 Claude 请求域名

先打开 Quantumult X,进入网络活动或请求日志,重新打开 Claude App,观察 Claude 请求的是哪个域名。

优先确认有没有这类请求:

claude.ai:443
https://claude.ai/api/account?

如果看到的是:

https://claude.ai/api/account?

本文后面的默认配置就可以直接用。

如果你看到的是:

https://api.claude.ai/api/account?

先不要急着照抄默认规则,后面“如果请求变成 api.claude.ai”一节有对应改法。

第二步:配置 MITM

打开 Quantumult X 配置文件,找到 [mitm] 部分。

如果你已经有 [mitm],不要再新建一个 [mitm],只需要把 claude.ai 加到原来的 hostname 后面。

例如你原本是:

[mitm]
hostname = example.com, example.org

改成:

[mitm]
hostname = example.com, example.org, claude.ai

如果你原本没有配置过 MITM,可以添加:

[mitm]
hostname = claude.ai

保存配置后,确认 Quantumult X 的 MITM 开关是开启状态。

第三步:安装并信任 Quantumult X 证书

只有把 Quantumult X 的 CA 证书安装并信任,Quantumult X 才能解密 HTTPS 请求并让 rewrite 对 https://claude.ai/api/account? 生效。

一般流程是:

  1. 打开 Quantumult X。
  2. 进入设置或 MitM 相关页面。
  3. 生成并安装 CA 证书。
  4. iOS 会跳转到描述文件安装流程。
  5. 安装描述文件。
  6. 回到 iOS 设置,手动信任证书。

iOS 信任路径通常是:

iOS 设置
→ 通用
→ 关于本机
→ 证书信任设置
→ 打开 Quantumult X CA 的完全信任

这一步经常被漏掉。只安装证书但没有在“证书信任设置”里打开信任,MITM 仍然不会真正生效。

第四步:创建脚本文件

在 iPhone 上打开“文件”App,进入:

我的 iPhone / Quantumult X / Scripts

这是脚本必须存放的位置。建议按下面的方式逐级确认:

文件 App
→ 浏览
→ 我的 iPhone
→ Quantumult X
→ Scripts

如果你在“我的 iPhone”下面看不到 Quantumult X 文件夹,可以先打开一次 Quantumult X,确认应用已经创建本地目录;也可以在 Quantumult X 内部的脚本管理页面新建脚本。

建议准备两个脚本文件:

claude_force_logout_stable.js
claude_force_logout_aggressive.js

两个文件都放在:

我的 iPhone / Quantumult X / Scripts

注意文件名要完全一致,尤其是:

  1. 不要写成 .js.txt
  2. 不要把下划线写成短横线。
  3. 不要改大小写。
  4. 不要放到 DownloadsiCloud Drive 或其他目录。
  5. 不要把脚本内容粘到 Quantumult X 配置文件里,脚本和配置是两个不同位置。

第五步:稳定版脚本

稳定版用于第一轮尝试。它只处理 claude.ai/api/account,匹配范围小,误伤概率最低。

新建文件:

claude_force_logout_stable.js

把下面脚本完整复制进去:

/**
 * Claude iOS Force Logout for Quantumult X
 *
 * File name:
 *   claude_force_logout_stable.js
 *
 * Storage path on iPhone:
 *   文件 App / 浏览 / 我的 iPhone / Quantumult X / Scripts
 *
 * Quantumult X usage:
 *   Use with "script-echo-response", not "script-response-body".
 *
 * Mode:
 *   Stable / precise.
 *
 * Purpose:
 *   Return a synthetic 401 response for Claude account endpoint,
 *   so Claude iOS App treats the old session as expired and goes
 *   back to the login page.
 */

const requestUrl = $request && $request.url ? $request.url : "";
const expiredAt = "Thu, 01 Jan 1970 00:00:00 GMT";

function expireCookie(name, domain) {
  return [
    `${name}=`,
    `Expires=${expiredAt}`,
    "Max-Age=0",
    "Path=/",
    `Domain=${domain}`,
    "Secure",
    "HttpOnly",
    "SameSite=Lax"
  ].join("; ");
}

console.log("[Claude Force Logout][stable] matched: " + requestUrl);
$notify("Claude Force Logout", "stable matched /api/account", requestUrl);

const body = JSON.stringify({
  error: {
    type: "session_expired",
    message: "Session expired. Please log in again."
  }
});

const headers = {
  "Content-Type": "application/json; charset=utf-8",
  "Cache-Control": "no-store",
  "Pragma": "no-cache",
  "Expires": "0",

  // Quantumult X 的 headers 是对象,重复 Set-Cookie 不一定稳定。
  // 这里用不同大小写分别写出两条过期 cookie,提高兼容性。
  "Set-Cookie": expireCookie("sessionKey", "claude.ai"),
  "set-cookie": expireCookie("routingHint", "claude.ai")
};

$done({
  status: "HTTP/1.1 401 Unauthorized",
  headers: headers,
  body: body
});

稳定版脚本做了三件事:

  1. 在日志里输出 [Claude Force Logout][stable] matched,方便确认是否命中。
  2. 弹出一条 Quantumult X 通知,显示脚本已匹配 /api/account
  3. 返回 401 Unauthorized,并尝试清掉旧的 sessionKeyroutingHint

第六步:更积极版脚本

如果稳定版没有效果,或者你在 Quantumult X 日志里看到 Claude 实际请求的是 api.claude.ai,再使用这个更积极版。

积极版做了两类加强:

  1. 配合 rewrite 同时匹配 claude.aiapi.claude.ai
  2. 响应头里尝试清理更多 domain 变体,并增加 Clear-Site-Data

新建文件:

claude_force_logout_aggressive.js

把下面脚本完整复制进去:

/**
 * Claude iOS Force Logout for Quantumult X
 *
 * File name:
 *   claude_force_logout_aggressive.js
 *
 * Storage path on iPhone:
 *   文件 App / 浏览 / 我的 iPhone / Quantumult X / Scripts
 *
 * Quantumult X usage:
 *   Use with "script-echo-response", not "script-response-body".
 *
 * Mode:
 *   Aggressive / broader account-endpoint matching.
 *
 * Use this only when:
 *   1. Stable mode did not bring Claude iOS back to login page; or
 *   2. Quantumult X logs show requests to api.claude.ai.
 *
 * Disable the rewrite immediately after Claude shows the login page.
 */

const requestUrl = $request && $request.url ? $request.url : "";
const expiredAt = "Thu, 01 Jan 1970 00:00:00 GMT";
const cookieNames = ["sessionKey", "routingHint"];
const cookieDomains = ["claude.ai", ".claude.ai", "api.claude.ai"];

function expireCookie(name, domain) {
  return [
    `${name}=`,
    `Expires=${expiredAt}`,
    "Max-Age=0",
    "Path=/",
    `Domain=${domain}`,
    "Secure",
    "HttpOnly",
    "SameSite=Lax"
  ].join("; ");
}

const expiredCookies = [];
for (const domain of cookieDomains) {
  for (const name of cookieNames) {
    expiredCookies.push(expireCookie(name, domain));
  }
}

console.log("[Claude Force Logout][aggressive] matched: " + requestUrl);
$notify("Claude Force Logout", "aggressive matched /api/account", requestUrl);

const body = JSON.stringify({
  error: {
    type: "session_expired",
    message: "Session expired. Please log in again."
  }
});

const headers = {
  "Content-Type": "application/json; charset=utf-8",
  "Cache-Control": "no-store, no-cache, must-revalidate, max-age=0",
  "Pragma": "no-cache",
  "Expires": "0",

  // 部分客户端会忽略这个头,但加上它可以更积极地提示清理站点数据。
  // 只在 claude.ai / api.claude.ai 的 /api/account 临时使用。
  "Clear-Site-Data": "\"cookies\", \"storage\", \"cache\""
};

// Quantumult X 的 headers 是对象,不能自然表达多条同名 Set-Cookie。
// 这里故意使用不同大小写的 Set-Cookie 头名,尽量让多条过期 cookie 被写出。
// 如果 Quantumult X 或系统网络栈最终只保留其中一条,也不会影响 401 退出登录的核心逻辑。
const setCookieHeaderNames = [
  "Set-Cookie",
  "set-cookie",
  "SET-COOKIE",
  "Set-cookie",
  "sEt-Cookie",
  "seT-Cookie"
];

for (let i = 0; i < expiredCookies.length && i < setCookieHeaderNames.length; i++) {
  headers[setCookieHeaderNames[i]] = expiredCookies[i];
}

$done({
  status: "HTTP/1.1 401 Unauthorized",
  headers: headers,
  body: body
});

积极版仍然只建议用于 /api/account。不要写成匹配 Claude 的所有接口,否则登录后会继续异常。

第七步:添加 rewrite 规则

继续编辑 Quantumult X 配置文件,找到 [rewrite_local]

稳定版 rewrite

^https:\/\/claude\.ai\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_stable.js

如果你的配置里还没有 [rewrite_local],完整写法是:

[rewrite_local]
^https:\/\/claude\.ai\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_stable.js

更积极版 rewrite

如果稳定版无效,或者日志里出现 api.claude.ai,把稳定版规则注释掉,改用这一条:

^https:\/\/(?:claude\.ai|api\.claude\.ai)\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_aggressive.js

完整写法是:

[rewrite_local]
^https:\/\/(?:claude\.ai|api\.claude\.ai)\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_aggressive.js

这里有几个容易写错的地方:

  1. 使用的是 script-echo-response
  2. 不是 script-response-body
  3. 规则匹配的是 /api/account
  4. 稳定版脚本名是 claude_force_logout_stable.js
  5. 积极版脚本名是 claude_force_logout_aggressive.js
  6. 规则应该放在 [rewrite_local] 下面。
  7. 稳定版和积极版不要同时开启,先开稳定版,无效再切积极版。

为什么用 script-echo-response

因为这个场景需要 Quantumult X 直接构造一个完整响应,包括 HTTP 状态码、headers 和 body。script-echo-response 更接近 Charles Rewrite 里“直接返回一个伪造响应”的效果。

第八步:确认 Quantumult X 开关

在运行 Claude App 前,检查 Quantumult X:

  1. 代理已开启。
  2. MITM 已开启。
  3. Rewrite 已开启。
  4. 配置文件已保存并重新加载。
  5. [mitm] 里包含 claude.ai
  6. [rewrite_local] 里有刚才那条规则。
  7. Scripts 目录里有对应脚本。
  8. 稳定版只开启 claude_force_logout_stable.js 对应 rewrite。
  9. 积极版只开启 claude_force_logout_aggressive.js 对应 rewrite。

如果你不确定配置是否重新加载,可以在 Quantumult X 里手动更新或重新载入配置。

第九步:触发修复

按下面顺序操作:

  1. 打开 Quantumult X。
  2. 确认代理、MITM、rewrite 都已经开启。
  3. 后台彻底划掉 Claude App。
  4. 重新打开 Claude App。
  5. 观察 Quantumult X 的日志或网络活动。

如果稳定版规则命中,你应该能看到日志:

[Claude Force Logout][stable] matched

如果积极版规则命中,你应该能看到日志:

[Claude Force Logout][aggressive] matched

也可能看到 Quantumult X 弹出通知:

Claude Force Logout
stable matched /api/account

这说明 Claude App 的 /api/account 请求已经被脚本接管。

如果一切正常,Claude iOS App 应该会从 Something went wrong / Try again 返回登录页。

第十步:成功后立刻关闭规则

这是最重要的一步。

一旦 Claude App 出现登录页,马上回到 Quantumult X,把 rewrite 规则关掉。

如果你用的是稳定版,把这一行注释掉:

;^https:\/\/claude\.ai\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_stable.js

如果你用的是积极版,把这一行注释掉:

;^https:\/\/(?:claude\.ai|api\.claude\.ai)\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_aggressive.js

也可以直接删除这行。

如果你不再需要 MITM Claude,也可以从 [mitm]hostname 里移除:

claude.ai
api.claude.ai

为什么必须关闭?

因为只要这条规则还开着,Claude App 每次请求 /api/account 都会被 Quantumult X 强制返回 401 Unauthorized。你即使重新登录,App 也可能继续被踢回登录态失效,导致新的异常。

这个规则只应该短时间开启,用完就关。

如何判断 MITM 和 rewrite 是否生效

在 Quantumult X 网络活动里观察 Claude 请求。

如果看到:

claude.ai:443
https://claude.ai/api/account?

旁边有绿色开锁,一般说明 MITM 已经生效。

如果请求旁边有粉色铅笔图标,通常说明 rewrite 规则命中了。

如果日志中出现:

[Claude Force Logout][stable] matched

或:

[Claude Force Logout][aggressive] matched

说明脚本已经执行。

如果既没有绿色开锁,也没有脚本日志,大概率是 MITM、证书信任、rewrite 开关或域名匹配没有配置好。

如果没有效果,按这个顺序排查

先检查 MITM:

  1. [mitm] 里是否有 hostname = claude.ai
  2. Quantumult X 的 MITM 功能是否开启。
  3. iOS 是否已经信任 Quantumult X CA。
  4. 网络活动中 claude.ai:443 是否显示绿色开锁。

再检查 rewrite:

  1. 规则是否写在 [rewrite_local] 下面。
  2. Quantumult X 的 rewrite 开关是否开启。
  3. 规则是否是 script-echo-response
  4. 规则里的正则是否匹配 /api/account

再检查脚本:

  1. 脚本是否放在 我的 iPhone / Quantumult X / Scripts
  2. 稳定版文件名是否严格为 claude_force_logout_stable.js
  3. 积极版文件名是否严格为 claude_force_logout_aggressive.js
  4. 文件是否真的以 .js 结尾,而不是 .js.txt
  5. 脚本内容是否完整复制。

最后检查 Claude 实际请求:

  1. Claude App 是否真的请求 https://claude.ai/api/account?
  2. 是否请求了别的域名。
  3. 是否根本没有发起 /api/account 请求。

如果请求变成 api.claude.ai

有些情况下,你在日志里看到的可能不是:

https://claude.ai/api/account?

而是:

https://api.claude.ai/api/account?

这时需要同时改 MITM 和 rewrite。

MITM 改成:

[mitm]
hostname = claude.ai, api.claude.ai

rewrite 改为积极版:

^https:\/\/(?:claude\.ai|api\.claude\.ai)\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_aggressive.js

也可以写成两条更直观的规则:

[rewrite_local]
^https:\/\/claude\.ai\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_aggressive.js
^https:\/\/api\.claude\.ai\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_aggressive.js

不过没有必要一开始就扩大范围。建议先根据 Quantumult X 网络活动里实际看到的域名来配置。

常见错误

这个方案需要伪造响应,让 App 接收 401 Unauthorized 和过期 cookie。

所以 Set-Cookie 必须写在 response headers。写在 request headers 不会达到清理 App session 的效果。

2. 用了 script-response-body

script-response-body 更偏向修改服务端已经返回的 body。

这个场景需要直接构造响应,建议使用:

script-echo-response

3. 忘记信任证书

只在 Quantumult X 里生成或安装证书还不够。iOS 必须在“证书信任设置”里打开完全信任。

4. 成功后忘记关闭规则

这是最容易导致新问题的错误。

如果规则一直开着,Claude App 会一直拿到伪造的 401 Unauthorized,登录后也可能继续异常。

5. 请求域名不一致

规则默认只匹配:

claude.ai

如果实际请求是:

api.claude.ai

就需要按前面的方式修改 MITM 和 rewrite。

推荐的完整配置片段

如果你的 Claude App 请求的是 claude.ai,稳定版最终配置可以像这样:

[rewrite_local]
^https:\/\/claude\.ai\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_stable.js

[mitm]
hostname = claude.ai

如果你需要同时兼容 claude.aiapi.claude.ai,积极版最终配置可以像这样:

[rewrite_local]
^https:\/\/(?:claude\.ai|api\.claude\.ai)\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_aggressive.js

[mitm]
hostname = claude.ai, api.claude.ai

如果你的配置文件里已经有 [rewrite_local][mitm],不要重复创建同名 section,只把对应规则和 hostname 合并进去。

例如:

[rewrite_local]
原来的规则 1
原来的规则 2
^https:\/\/claude\.ai\/api\/account\/?(?:\?.*)?$ url script-echo-response claude_force_logout_stable.js

[mitm]
hostname = 原来的域名1, 原来的域名2, claude.ai

最后提醒

这个方法本质上是一次临时的登录态清理动作,不是长期代理规则。

正确使用方式是:

  1. 开启 MITM 和 rewrite。
  2. 让 Claude App 命中一次 /api/account
  3. App 回到登录页。
  4. 立刻关闭 rewrite。
  5. 重新登录 Claude。

不要把真实 cookie 发给别人,也不要长期拦截 Claude 的账号接口。这个规则只用于解决 iOS App 卡在旧 session 的问题。

文章标签: Default

上一篇 : 已经是第一篇文章了~
下一篇 : 都 2026 年了,我们为什么还要写博客
阅读进度 0%