Bitbucket私有库Composer安装失败的根本原因是未配置OAuth令牌导致401错误,必须通过auth.json配置App Password并设置vcs仓库地址与包名一致。

Bitbucket 私有库安装失败:Composer 报 401 Unauthorized 或 Could not fetch
根本原因是 Composer 默认不携带 Bitbucket OAuth 令牌,而私有仓库需要身份认证。直接在 composer.json 里写 https://bitbucket.org/xxx/yyy.git 会触发匿名请求,必然被拒绝。
解决路径只有一条:让 Composer 在访问 Bitbucket 时自动带上有效令牌。这不是靠改 repositories 配置能绕过的,必须配置全局或项目级的 auth.json。
- Bitbucket 不支持 HTTP Basic Auth(即用户名+密码),仅接受
app password或OAuth consumer(推荐前者) - 令牌必须拥有
repository:read权限(如果是私有库,还需repository:write如果要 push) -
auth.json文件位置优先级:项目根目录auth.json>COMPOSER_HOME/auth.json(通常是~/.composer/auth.json)
生成 Bitbucket App Password 并写入 auth.json
App Password 是最轻量、最可控的身份凭证方式,比 OAuth consumer 更易维护,也无需回调地址等配置。
- 登录 Bitbucket → 左下角头像 → Personal settings → App passwords → Create app password
- 命名如
composer-read-private-repos,勾选权限:Repositories: Read(必须),Account: Read(可选,用于获取用户信息) - 生成后立即复制该密码(仅显示一次!)
- 在项目根目录或
~/.composer/下创建auth.json,内容如下:
{
"bitbucket.org": {
"consumer_key": "",
"consumer_secret": "",
"oauth_token": "",
"oauth_token_secret": "",
"password": "APP_PASSWORD_HERE"
}
}
注意:password 字段值就是刚复制的 App Password;其他 OAuth 字段留空即可 —— Composer 会自动识别并使用 password 模式进行 Basic Auth(它把 username 当作你的 Bitbucket 用户名,password 当作 App Password)。
监控一个或多个 GitCode 仓库的 PR,通过 OpenClaw Gateway 自动执行 AI 审查,发布 PR 评论,并发送钉钉和企业微信通知。
composer.json 中正确声明私有仓库
不能只靠 auth.json 就完事。Composer 还得知道这个包从哪来、怎么解析。关键点在于:用 vcs 类型 + 完整 HTTPS Git 地址,并确保包名与仓库实际命名一致。
- Bitbucket 的私有仓库 URL 格式是
https://bitbucket.org/{workspace}/{repo-slug}.git,不是 SSH 或网页链接 -
name字段必须匹配目标包的name(即vendor/name),否则 Composer 找不到匹配项 - 不要加
dist或source配置 —— VCS 类型下 Composer 自动处理
{
"repositories": [
{
"type": "vcs",
"url": "https://bitbucket.org/myorg/my-private-package.git"
}
],
"require": {
"myorg/my-private-package": "^1.0"
}
}
运行 composer install 或 composer update 时,Composer 会读取 auth.json,对 bitbucket.org 域名的所有请求自动附加 Authorization: Basic ... 头,完成认证。
调试与常见陷阱
如果仍报错,别急着重试,先确认三件事:
- 运行
composer config --global --list | grep bitbucket看是否意外设置了冲突的 global auth 配置 - 检查
auth.json是否被 Git 忽略(应加入.gitignore!),但确保它真实存在于 Composer 查找路径中 - 错误信息含
Failed to clone https://bitbucket.org/...?说明 Composer 没读到auth.json,或令牌权限不足;含Could not parse version constraint?大概率是composer.json里name和 require 的不一致 - Bitbucket workspace 名称大小写敏感,
MyOrg≠myorg,URL 和name必须完全一致
App Password 一旦失效(比如被删除或过期),Composer 不会提示“令牌过期”,只会反复报 401 —— 这时候最容易卡住。建议把 App Password 的创建时间、用途记在密码管理器里,而不是靠记忆。

















