CouchDB 中的 _users 数据库不允许使用 HTTP OPTIONS 方法

Posted

技术标签:

【中文标题】CouchDB 中的 _users 数据库不允许使用 HTTP OPTIONS 方法【英文标题】:HTTP OPTIONS method not allowed for _users database in CouchDB 【发布时间】:2015-11-25 02:49:30 【问题描述】:

我正在尝试在从另一个域连接到 CouchDB 的应用程序中更改用户密码。我的代码或多或少与CouchDB Docs 中的示例相同,即获取文档,更改数据,然后将更改后的 PUT 请求发回。 PUT 请求出现问题 - 由于 CORS,浏览器在发送 PUT 请求之前尝试执行 OPTIONS 请求,但 OPTIONS 请求返回 405 Method Not Allowed。

有人知道如何解决这个问题吗?

以下是请求标头以防万一:

OPTIONS /_users/org.couchdb.user:clinic_admin HTTP/1.1
Host: localhost:15984
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: PUT
Origin: https://localhost:15000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/44.0.2403.157 Safari/537.36
Access-Control-Request-Headers: content-type, if-match
Accept: */*
Referer: https://localhost:15000/webapp/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,ja;q=0.6,sv;q=0.4,zh-CN;q=0.2

【问题讨论】:

【参考方案1】:

这里有两个选项。我更喜欢选项 #2,但我将从 #1 开始。

选项 1:正确配置 CORS

CouchDB 中的 405 错误通常是由于配置错误造成的,例如不包括所有可能的标头和方法,如果您想支持所有浏览器/设备,其中有很多。

在 PouchDB 团队中,我们将“最佳实践”集中到一个模块中:add-cors-to-couchdb,它应该适用于 CouchDB 1.6.1 和 CouchDB 2.0。运行:

npm install --global add-cors-to-couchdb
add-cors-to-couchdb http://example.com:5984 -u admin_username -p admin_password

这应该可以解决您的问题;如果没有,请查看PouchDB 或pouchdb-authentication 的测试,它们成功地使用此方法针对在localhost:5984 运行的数据库进行测试(包括更改用户密码,这是您正在尝试执行的操作)。

选项 2:使用反向代理避免 CORS

这确实是最好的选择。它更好有几个原因:

    花几分钟时间配置 Apache/nginx 以完全避免 CORS,避免以后尝试让 CORS 正常工作而让自己头疼 CORS 的性能不如 no-CORS,因为浏览器需要执行预检 OPTIONS 请求,这会增加额外的延迟,尤其是在复制期间 这在移动混合应用程序中也更容易; Cordova 有 a one-liner option 将某些域列入白名单并避免 CORS。

我通常使用 CouchDB 的 Nginx as a reverse proxy 指南并路由到在 example.com/couchdb 运行的数据库。例如:

location /couchdb 
    rewrite /couchdb/(.*) /$1 break;
    proxy_pass http://localhost:5984;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

请注意,这可能会破坏/_utils(Futon/Fauxton),但在这些情况下,最好的办法是通过 SSH 设置到您的服务器的反向隧道并在本地查看:

ssh -L3000:localhost:5984 user@example.com
# now open localhost:3000/_utils in a browser

您可能不希望 Futon/Fauxton 暴露在世人面前。

这里的优点是您可以使用 Nginx/Apache 阻止 CouchDB 的某些方法或某些部分,这通常比 CouchDB 中可用的 HTTP 选项更灵活。

【讨论】:

只是关于选项 1 的注释 - 虽然 add-cors-to-couchdb 是一个很棒的工具,但请注意 _bulk_docs 端点不会响应全局配置(至少在我的测试中)。 _bulk_docs 不允许 OPTIONS 请求,因此如果您让 CouchDB 在没有代理的情况下处理 CORS 请求,CORS 复制将失败。要对此进行测试,请在终端中尝试以下操作并注意 HTTP 405 错误响应:curl 'http://127.0.0.1:5984/database/_bulk_docs' -X OPTIONS -v【参考方案2】:

我没有直接连接到 CouchdB 实例,而是使用 Apache 作为代理,这样可以提供更多的灵活性。 CouchDB 有时会完全禁止 OPTIONS 请求(例如,_bulk_docs 只允许 POST,这会导致完全阻止复制的 405 错误)。为了在执行 CORS 请求时解决此问题,我将以下规则添加到配置我的代理的 .htaccess 文件中:

# ALWAYS ALLOW PREFLIGHT REQUESTS (COUCHDB FORBIDS THIS RESPONSE FOR _bulk_docs)
RewriteCond %REQUEST_METHOD OPTIONS
RewriteRule ^(.*)$ $1 [R=204,L]

# Continue with RewriteRules for the CouchDB URLs you want to proxy
# plus whatever authorization headers you might want to add
RewriteRule db/(.*) http://couch.url:5984/database/$1 [P]

第一个 RewriteRule 捕获所有 OPTIONS 请求并返回一个空白 204,这告诉客户端可以继续处理他们的 CORS POST 请求。如果不是这种情况,OPTIONS 请求将被转发到 CouchDB,它会回复 405。无论您在 CouchDB 配置中允许什么方法,它都会这样做。

希望这对您的具体案例有所帮助。

【讨论】:

以上是关于CouchDB 中的 _users 数据库不允许使用 HTTP OPTIONS 方法的主要内容,如果未能解决你的问题,请参考以下文章

如何限制 CouchApp 对 CouchDB 的 `_user` 表的访问?

Cloudant 身份验证:缺少 _users 数据库

CouchDB查询文档

CouchDB查询文档

CouchDB 添加没有预定义管理员的用户

CouchDB 重写规则以更新处理程序导致 405 方法不允许