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



我试图从从另一个域连接到CouchDB的应用程序中更改用户的密码。我的代码与CouchDB文档中的示例或多或少相同,即获取文档,更改数据,然后将更改发送回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

这里有两个选项。我更喜欢选项#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

这应该解决你的问题;如果没有,请查看使用此方法对运行在localhost:5984上的数据库进行测试的PouchDB或PouchDB -authentication的测试(包括更改用户密码,这就是您正在尝试做的)。

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

这真的是最好的选择。它之所以更好,有以下几个原因:

  1. 花几分钟配置Apache/nginx来避免CORS,节省你以后试图让CORS正确工作的头痛
  2. CORS比无CORS性能差,因为浏览器需要做预飞行选项请求,这增加了额外的延迟,特别是在复制期间
  3. 这在移动混合应用中也更容易;Cordova有一个单行选项来将某些域列入白名单并避免CORS。

我通常使用Nginx作为CouchDB的反向代理指南,并路由到运行在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选项更灵活。

我没有直接连接到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]

第一个rewriterrule捕获所有OPTIONS请求并返回一个空白204,这告诉客户端可以继续执行CORS POST请求。如果不是这样,OPTIONS请求将被转发给CouchDB, CouchDB将返回405。无论您在CouchDB配置中允许使用什么方法,它都会这样做。

最新更新