一次 npm 更新强制2FA导致的发布失败的排查:403、2FA、Recovery Code、Granular Token 的混乱体验

最近在更新发布自己的一个 npm 包(branch-commit-compare)时踩了一堆坑。问题本身不复杂,但 npm 新旧验证体系在 UI 和流程上混杂一起,导致排查成本远高于必要水平。这里记录一下整个过程,避免别人重复踩坑。


背景

我本地执行:

复制代码
npm publish

结果直接报:

dart 复制代码
npm ERR! 403 Forbidden - PUT https://registry.npmjs.org/xxx
Two-factor authentication or granular access token with bypass 2fa enabled is required to publish packages.

很明确:npm 要求 2FA 或具有 bypass-2FA 权限的 token 才允许发布。问题在于 ------ 我当时的 2FA 状态看起来"不完整"。


一、UI 误导:npm 只给我一个「Security Key」选项

进入 npm 账户的 Security 页面 → Enable 2FA,看到的 2FA 方式只有:

Security Key(USB/NFC、生物识别等)

正常情况下,npm 应该同时提供:

  • Authenticator App(TOTP)
  • Security key(FIDO U2F)
  • Recovery codes

但在我这里,点击 Enable 2FA 直接跳到 Security Key,没有 TOTP 选项

这会带来一个明显问题:

npm CLI 的 --otp=xxxxxx 只能输入 TOTP 码,不能输入恢复码、不能输入 security-key 相关内容。

也就是说:只启用 Security Key = 无法在 CLI 完成 publish


二、我以为自己拿到的是「秘钥」,实际上那是 Recovery Codes

复制代码
e496c18fe4b39b0e2e1d2d4c7958c561fd3a2526f31ce7aea8394413b1826576
061baf4f296ea7e94c416eb9be80ecd47843ae7b957916f7d788d7310cefc053
4c7feaaca38231ca76222bab37eea9ff1dc69ccf90398900025c4dd03226002b
1886537d1acf213f1ea27329bd7ecdc6e6934397a55a1b1d5882698617f738ed
8b6abe5645ffb5e09d6b6aad2955d8ac9c64bf971751845cbf2afd453476473d

UI 只显示一串普通文本,把它描述成"安全密钥"。但实际那是 Recovery Codes(一次性备份码),不是 TOTP Secret,也不是 token。

把换行删掉、合并成一行都没用,它压根不是 TOTP。

这导致我误以为 CLI 能用它 publish → 当然失败。


三、npm profile get 暴露核心真相

执行:

arduino 复制代码
npm profile get

返回:

matlab 复制代码
two-factor auth │ auth-and-writes

含义:

  • 你已经启用了 2FA,但只启用了 写操作保护
  • npm 要求:发布时必须提供 TOTP
  • Recovery Code 和 Security Key 都不能替代 TOTP

结论:你的 2FA 配置不完整,CLI 肯定 403


四、可行的解决路径:创建 Granular Token 并开启 bypass 2FA

既然 npm CLI 强制需要 TOTP,而 UI 又不给你配置 TOTP,那就只能走另一条路:

1. 创建 Granular Access Token

进入 npm → 头像 → Access Tokens → Create New Token

选择:

  • 类型:Granular / Automation Token
  • 权限:选择你要 publish 的包
  • 关键:勾选 "Bypass two-factor authentication"

创建后会出现真正的一次性 token(长字符串),这才是发布用的。

2. 写入本地 ~/.npmrc

bash 复制代码
echo "//registry.npmjs.org/:_authToken=你的token" >> ~/.npmrc

3. 再次发布

复制代码
npm publish

→ 一次通过。


五、根因:npm 的验证系统正在剧烈切换

npm 现在要求:

  • 经典 token 全部废弃
  • granular token 成为唯一可用的 token
  • granular token 默认需要 2FA
  • 而 2FA 又分 TOTP / security key
  • 但 UI 渐进式上线,部分用户只能看到 security key
  • CLI 又要求 TOTP

这就造成一个现象:

你启用了"半套"2FA,UI 显示正常,但 CLI 无法完成发布。


六、最终解决方案总结

  1. npm profile get 显示 auth-and-writes → CLI 必须 OTP
  2. UI 只给你 Security Key,没有 TOTP → CLI 永远无法输入正确 OTP
  3. Recovery Code 不是 OTP → 无效
  4. 唯一可行方法 → 创建带 bypass-2FA 的 granular token
  5. 写入本地 .npmrc 后发布即可

七、给后来者的建议

如果你正在启用 npm 的 2FA:

  • 一定要启用 TOTP(Authenticator App)
    而不是只启用 Security Key (但是官方只给了这种方式)
  • Granular Token 是目前唯一不会踩坑的方式(特别是 CI/CD)
  • 不要被恢复码误导,它不是 OTP
  • 25年12月9号强制必须使用2FA或者绕过2FA的token 我今天12月12太多人在操作了,官网巨卡无比

结语

npm 的验证体系正在重构,UI 不统一、流程半旧半新,是这次踩坑的根本原因。如果你遇到类似的 403 + 要求 2FA,又找不到 TOTP,多半和我一样卡在了"只有 Security Key"这个界面。

解决方法就是:绕开 2FA,使用带 bypass 权限的 granular token 发布

相关推荐
Justin3go4 小时前
HUNT0 上线了——尽早发布,尽早发现
前端·后端·程序员
怕浪猫5 小时前
第一章 JSX 增强特性与函数组件入门
前端·javascript·react.js
铅笔侠_小龙虾5 小时前
Emmet 常用用法指南
前端·vue
钦拆大仁5 小时前
跨站脚本攻击XSS
前端·xss
VX:Fegn08956 小时前
计算机毕业设计|基于springboot + vue校园社团管理系统(源码+数据库+文档)
前端·数据库·vue.js·spring boot·后端·课程设计
ChangYan.7 小时前
直接下载源码但是执行npm run compile后报错
前端·npm·node.js
skywalk81637 小时前
在 FreeBSD 上可以使用的虚拟主机(Web‑Hosting)面板
前端·主机·webmin
ohyeah8 小时前
深入理解 React 中的 useRef:不只是获取 DOM 元素
前端·react.js
MoXinXueWEB8 小时前
前端页面获取不到url上参数值
前端
低保和光头哪个先来9 小时前
场景6:对浏览器内核的理解
开发语言·前端·javascript·vue.js·前端框架