直接结论:不是网络问题,也不是 composer 坏了,是 auth.json 里存的 github/gitlab/私仓 token 已过期或权限不足;需重生成带 read:packages 等必要 scope 的 classic pat,用 composer config --global --auth github-oauth.github.com 安全写入,并执行 composer clear-cache 验证生效。

Composer install 时提示 “Token has expired” 怎么办
直接结论:不是网络问题,也不是 Composer 坏了,是 auth.json 里存的 GitHub/GitLab/私仓 Token 已过期或权限不足。Composer 在拉取私有包或限流接口时会校验该 Token,过期后就卡在认证环节。
常见现象:composer install 卡在 Downloading ... 或直接报错 Failed to download vendor/package: Token has expired;composer update 同样失败,但 composer show 可能仍能查到包信息(缓存未清)。
- 先确认 Token 类型:GitHub 的 Personal Access Token(PAT)默认有效期为 30 天(若勾选了
no expiration则永久,但建议别这么干);GitLab 的 Access Token 也需手动设有效期 - 检查是否用了
composer config --global github-oauth.github.com <token></token>—— 这种方式会把 Token 写进全局auth.json,容易被遗忘 - 项目级
auth.json(位于项目根目录)优先级高于全局,但若两者都存在且 Token 都过期,照样失败
如何安全生成新 Token 并注入 Composer
重点不是“怎么生成”,而是“生成时必须勾选哪些 scope”——少一个,后续拉包就 403。
以 GitHub 为例(GitLab 类似):
- 访问
https://github.com/settings/tokens/new - Token description 建议写明用途,比如
composer-for-myproject-2024,方便后续审计或回收 - 必选 scope:
read:packages(读取 GitHub Packages)、delete:packages(删包,非必需)、write:packages(推包,非必需),但最关键的是read:org—— 如果你依赖的私包在组织(Org)下,没这个权限,即使 Token 没过期也会 404 - 生成后,**立即复制**,页面关闭后无法再次查看明文
注入方式推荐项目级,避免污染全局配置:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
echo '{"github-oauth": {"github.com": "ghp_abc123..."}}' > auth.json
composer config --auth github-oauth.github.com ghp_abc123...
注意:composer config --auth 会自动写入项目 auth.json,且不会覆盖已有字段;而直接 echo 覆盖需谨慎,确保 JSON 格式合法。
为什么更新 Token 后还是报错?排查顺序
Token 更新了,但 Composer 依然用旧凭据——不是它不讲武德,是你没让它“重新认人”。
- 运行
composer clear-cache:清除已缓存的元数据和下载包,否则它可能继续尝试用旧 Token 请求已缓存的 URL - 检查
auth.json是否被 Git 忽略:如果.gitignore里有auth.json,CI 环境根本读不到你的新 Token,得改用环境变量方式(见下条) - CI/CD 场景务必用
COMPOSER_AUTH环境变量替代文件:例如export COMPOSER_AUTH='{"github-oauth":{"github.com":"ghp_newtoken"}}',这样既安全又绕过文件读取逻辑 - 验证是否生效:运行
composer config --list --auth,确认输出中github-oauth.github.com的值是你刚设的新 Token 前几位(Composer 会掩码显示)
长期项目怎么避免反复掉坑
Token 过期不是偶发故障,是设计使然。靠“想起来再换”迟早出事。
- 所有生产级项目,把 Token 管理纳入部署流程:CI 脚本里用密钥管理服务(如 GitHub Secrets / GitLab CI Variables)注入
COMPOSER_AUTH,而不是手动生成、手写进文件 - 禁止把
auth.json提交进 Git:哪怕加了.gitignore,也常有人误提交;一旦泄露,相当于交出仓库只读权限 - 定期轮换(比如每 90 天):GitHub 支持 token revocation API,可脚本化清理旧 Token;GitLab 也提供列表与删除接口
- 留意 Composer 版本:低于 2.2 的版本对某些新 scope(如
read:org)支持不完整,升级到^2.5更稳
最易被忽略的一点:GitHub 的 Token 权限变更(比如组织管理员禁用了某 Token 的 read:org),不会触发“过期”提示,而是静默返回 403 —— 此时看日志只会显示 “Could not parse version constraint”,得结合 composer -v install 查真实 HTTP 状态码。










