问题 链接到标题
需要给 CouchDB 创建一个凭证,让其他节点能拉取数据库做数据同步。最初想的是"API Key"——一个静态字符串,像大多数现代服务那样,拿来就能用在 curl 或代码中。
迷惑:CouchDB 有没有 API Key? 链接到标题
很多人提到的 CouchDB “API Key” 其实来自 IBM Cloudant(托管的 CouchDB 兼容服务),它提供了 POST /_api_keys 端点,返回一个 key 和 password。
但原生 Apache CouchDB 没有这个端点。一个常见的误解是把通过 _config/admins/<username> 创建的 server-level admin 当成了"API Key"——它有用户名和密码,需要 Basic Auth,本质上就是一个管理员账号。
方案探索 链接到标题
1. Server-level Admin 链接到标题
通过 PUT /_node/_local/_config/admins/sync_obsidian 在 _config 中注册一个同步用账号。
- 优点:简单,CouchDB
_configAPI 一行命令搞定 - 缺点:全局管理员权限,对服务器上所有数据库有完全控制权,权限过宽。只能做数据同步,不应该有删库的权限
2. JWT 认证 链接到标题
CouchDB 从 3.x 开始支持 JWT 认证,通过配置 jwt_keys 和 jwt_authentication_handler 启用。
工作原理:
- 外部服务器用私钥签发 JWT
- CouchDB 用预配置的公钥验证签名
- 验证通过后,
sub字段作为用户名,_couchdb.roles作为角色
JWT 和 API Key 的本质区别:
| API Key | JWT | |
|---|---|---|
| 形态 | 静态字符串 | 签名的 token |
| 验证方式 | 服务端查表 | 公钥验签 |
| 谁可生成 | 服务端 | 持有私钥者 |
| 撤销方式 | 直接删除 | 需维护黑名单 |
对于自建 CouchDB,JWT 的引入成本较高:
- 需要维护签发服务
- 需要配置密钥管理
- token 有有效期,过期后需要刷新
3. _users 标准用户(最终方案) 链接到标题
CouchDB 的 _users 数据库存储所有标准用户,每个用户是一个文档:
{
"_id": "org.couchdb.user:sync_obsidian",
"type": "user",
"name": "sync_obsidian",
"roles": []
}
认证方式:Basic Auth,curl -u username:password。
通过数据库的 _security 端点精确控制每个数据库的权限:
{
"admins": { "names": ["admin"], "roles": ["_admin"] },
"members": { "names": ["sync_obsidian"], "roles": [] }
}
这样 sync_obsidian 只能读/写指定的数据库,无法遍历同机其他数据库。
方案对比 链接到标题
| 方案 | 原生支持 | 权限粒度 | 复杂度 |
|---|---|---|---|
| Server-level Admin | 是 | 全局 | 低 |
| JWT 认证 | 是 | 依赖 token 内容 | 高 |
| _users 标准用户 | 是 | 可精确到单库 | 低 |
_users 标准用户是功能、安全、复杂度之间的最佳平衡点。
实际操作 链接到标题
创建用户只需两步:
# 1. 在 _users 数据库创建用户
curl -X PUT http://couchdb:5984/_users/org.couchdb.user:sync_user \
-u admin:password \
-H "Content-Type: application/json" \
-d '{
"_id": "org.couchdb.user:sync_user",
"name": "sync_user",
"password": "strong_password",
"roles": [],
"type": "user"
}'
# 2. 配置数据库权限
curl -X PUT http://couchdb:5984/mydb/_security \
-u admin:password \
-H "Content-Type: application/json" \
-d '{
"admins": { "names": ["admin"], "roles": ["_admin"] },
"members": { "names": ["sync_user"], "roles": [] }
}'
其他节点使用普通的 Basic Auth 即可连接:
curl -u sync_user:strong_password http://couchdb:5984/mydb
总结 链接到标题
- 原生 CouchDB 没有 API Key 的概念,这是托管版本才有的功能
- 想要跨节点同步凭证,
_users标准用户是最直接的方式 - JWT 认证虽然可行,但对于单库同步的场景来说太重了
- Basic Auth +
_users用户是所有 CouchDB 版本都支持的方案,简单可靠