CouchDB 2 是否跨节点同步用户会话?
Does CouchDB 2 sync user sessions across nodes?
我目前正在研究 docker-compose 设置,可用于部署 CouchDB 2 节点集群。我终于让节点正常工作并且跨节点同步数据,但除非我弄错了,否则 CouchDB 似乎不会同步用户会话。
我的设置有 3 个节点,并使用与 haproxy.cfg 几乎相同的 haproxy 设置。根据我的配置,haproxy 将端口 5984 上的传入流量路由到所有 3 个节点上的端口 5984。
假设管理员用户名 root
和密码 password
。
我首先登录:
curl -vX POST http://localhost:5984/_session -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=root&password=password'
注意返回的 AuthSession 在下面用作 AUTHSESSION。
然后,我发布以下内容:
curl -X PUT http://localhost:5984/mydb --cookie AuthSession=AUTHSESSION -H "X-CouchDB-WWW-Authenticate: Cookie" -H "Content-Type: application/x-www-form-urlencoded"
这通常会因“您不是服务器管理员”而失败。我可以继续发出相同的 PUT,它最终会成功,因为我假设 haproxy 最终将请求路由到我通过身份验证的单个节点。由于 haproxy 使用循环法,我有三分之一的机会命中目标节点。
我认为 CouchDB 2 可以处理跨节点同步用户会话。我是不是在做一个愚蠢的假设?
(请参阅 run cluster via docker-compose 以复制我的设置)
更新我的 docker-compose 设置的具体解决方案
根据@lossleader,您需要在 [couch_httpd_auth] 部分中设置秘密,以便它在节点之间是相同的。此外,您需要在 [admins] 部分设置相同的管理员用户名和密码。我在这里错过的细节是所有节点在 .ini 文件中必须具有完全相同的密码 hash。拥有相同的明文密码是不够的,否则每个节点都会生成自己的盐并生成不同的哈希值。
有关我的完整设置,请参阅 run cluster via docker-compose。
CouchDB 会话令牌只是用户密码盐、服务器机密和时间的 HMAC 散列。会话根本不存储在 CouchDB 中,即使在单节点系统上也是如此。所以没有什么可以同步的。
您可以,而且很多人都这样做,完全以编程方式在 CouchDB 外部生成会话。
简答:是。
长答案:
正如其他人评论的那样,couchdb 不知道它创建的会话,所以确实没有同步会话本身的机制,但是在创建会话 cookie 之前,您需要自己同步两个非会话的东西在集群的一个节点上将在任何其他节点上有效。
[couch_httpd_auth]
secret = foo
这是用于签署会话 cookie 的秘密值。如果在请求会话 cookie 时不存在,则将其设置为随机值。集群的每个节点自然会生成不同的值。
因此,在启动之前,请将此值设置为一个较大的随机值,但在集群的所有节点上都相同。
[admins]
foo = -pbkdf2-2cbae77dc3d2dadb43ad477d312931c617e2a726,cd135ad4d6eb4d2f916cba75935c3ce7,10
此部分包含每个管理员用户的加盐密码哈希。盐包含在会话 cookie 的签名中。在密码更改时,salt 会重新随机化,因此包含 salt 的效果是它会使密码更改之前的会话 cookie 无效。
您还需要此部分在所有节点上都相同。每个节点在对管理员密码进行哈希处理时都会生成一个随机盐。
最好在外部生成此部分作为节点配置自动化的一部分。
我希望这能让你开始。我们希望在未来的版本中改善这种情况,它显然反映了 couchdb 的预集群版本。
我目前正在研究 docker-compose 设置,可用于部署 CouchDB 2 节点集群。我终于让节点正常工作并且跨节点同步数据,但除非我弄错了,否则 CouchDB 似乎不会同步用户会话。
我的设置有 3 个节点,并使用与 haproxy.cfg 几乎相同的 haproxy 设置。根据我的配置,haproxy 将端口 5984 上的传入流量路由到所有 3 个节点上的端口 5984。
假设管理员用户名 root
和密码 password
。
我首先登录:
curl -vX POST http://localhost:5984/_session -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=root&password=password'
注意返回的 AuthSession 在下面用作 AUTHSESSION。
然后,我发布以下内容:
curl -X PUT http://localhost:5984/mydb --cookie AuthSession=AUTHSESSION -H "X-CouchDB-WWW-Authenticate: Cookie" -H "Content-Type: application/x-www-form-urlencoded"
这通常会因“您不是服务器管理员”而失败。我可以继续发出相同的 PUT,它最终会成功,因为我假设 haproxy 最终将请求路由到我通过身份验证的单个节点。由于 haproxy 使用循环法,我有三分之一的机会命中目标节点。
我认为 CouchDB 2 可以处理跨节点同步用户会话。我是不是在做一个愚蠢的假设?
(请参阅 run cluster via docker-compose 以复制我的设置)
更新我的 docker-compose 设置的具体解决方案
根据@lossleader,您需要在 [couch_httpd_auth] 部分中设置秘密,以便它在节点之间是相同的。此外,您需要在 [admins] 部分设置相同的管理员用户名和密码。我在这里错过的细节是所有节点在 .ini 文件中必须具有完全相同的密码 hash。拥有相同的明文密码是不够的,否则每个节点都会生成自己的盐并生成不同的哈希值。
有关我的完整设置,请参阅 run cluster via docker-compose。
CouchDB 会话令牌只是用户密码盐、服务器机密和时间的 HMAC 散列。会话根本不存储在 CouchDB 中,即使在单节点系统上也是如此。所以没有什么可以同步的。
您可以,而且很多人都这样做,完全以编程方式在 CouchDB 外部生成会话。
简答:是。
长答案:
正如其他人评论的那样,couchdb 不知道它创建的会话,所以确实没有同步会话本身的机制,但是在创建会话 cookie 之前,您需要自己同步两个非会话的东西在集群的一个节点上将在任何其他节点上有效。
[couch_httpd_auth]
secret = foo
这是用于签署会话 cookie 的秘密值。如果在请求会话 cookie 时不存在,则将其设置为随机值。集群的每个节点自然会生成不同的值。
因此,在启动之前,请将此值设置为一个较大的随机值,但在集群的所有节点上都相同。
[admins]
foo = -pbkdf2-2cbae77dc3d2dadb43ad477d312931c617e2a726,cd135ad4d6eb4d2f916cba75935c3ce7,10
此部分包含每个管理员用户的加盐密码哈希。盐包含在会话 cookie 的签名中。在密码更改时,salt 会重新随机化,因此包含 salt 的效果是它会使密码更改之前的会话 cookie 无效。
您还需要此部分在所有节点上都相同。每个节点在对管理员密码进行哈希处理时都会生成一个随机盐。
最好在外部生成此部分作为节点配置自动化的一部分。
我希望这能让你开始。我们希望在未来的版本中改善这种情况,它显然反映了 couchdb 的预集群版本。