简体   繁体   English

使用CouchDB PouchDB阻止身份验证弹出401

[英]Prevent Authentication popup 401 with CouchDB PouchDB

For a JavaScript web app (AngularJS based) I am using PouchDB replicating a CouchDB database on my server. 对于JavaScript Web应用程序(基于AngularJS),我使用PouchDB在我的服务器上复制CouchDB数据库。 Authentication in PouchDB works nicely with pouchdb-authentication . PouchDB中的身份验证pouchdb身份验证很好地协同工作。 I want to manage this through a html/js login screen. 我想通过html / js登录屏幕来管理它。

However, if the user enters wrong credentials, I receive a 401 Unauthorized from the CouchDB server that causes a browser popup asking for credentials. 但是,如果用户输入了错误的凭据,我会从CouchDB服务器收到401 Unauthorized ,导致浏览器弹出请求凭据。

How can I prevent this ugly Authentication popup and just handle everything from my javascript?! 如何防止这个丑陋的身份验证弹出窗口,只需处理我的javascript中的所有内容?!

I finally found the solution: 我终于找到了解决方案:

Edit the CouchDB config local.ini and change the HTTP Header sent in response: 编辑CouchDB config local.ini并更改响应中发送的HTTP Header:

WWW-Authenticate = Other realm="app"

Originally this is 原来这是

WWW-Authenticate = Basic realm="administrator"

or if it is commented, that's what is sent out anyway. 或者如果它被评论,那就是发送出去的东西。 The WWW-Authenticate = Basic apparently causes the browser to handle (failed) authentication by showing its modal. WWW-Authenticate = Basic显然导致浏览器通过显示其模态来处理(失败)身份验证。 Changing Basic to anything else makes the browser ignore it and you can deal with the login yourself. Basic更改为其他任何内容都会使浏览器忽略它,您可以自己处理登录。

Update 2015.12.18 更新2015.12.18

After a lot of testing I arrived at the second solution outlined. 经过大量的测试后,我得出了第二个解决方案。 All you need to do is install nginx with the headers-more-module. 您需要做的就是使用headers-more-module安装nginx。 Add the following to your nginx-config: 将以下内容添加到您的nginx-config:

location / {

    # forward all request headers to backend
    proxy_pass_request_headers on;

    # these settings come from the CouchDB wiki
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

    # your CouchDB backend
    proxy_pass http://127.0.0.1:5984;

    # replace WWW-Authenticate header in response if authorization failed
    more_set_headers -s 401 'WWW-Authenticate: Other realm="App"';
}

# location to handle access to Futon
location /_utils/ {

    # forward all request headers to backend
    proxy_pass_request_headers on;

    # these settings come from the CouchDB wiki
    proxy_set_header    Host               $host;
    proxy_set_header    X-Real-IP          $remote_addr;
    proxy_set_header    X-Forwarded-For    $proxy_add_x_forwarded_for;

    # your CouchDB backend
    proxy_pass http://127.0.0.1:5984;

    # DO NOT replace WWW-Authenticate header in response if authorization failed
    # more_set_headers -s 401 'WWW-Authenticate: Other realm="App"';

    # Handle redirects
    proxy_redirect default;
}

And your are set. 你的确定了。 You can continue using pouchdb-authentication or write your own login handler. 您可以继续使用pouchdb-authentication或编写自己的登录处理程序。

Original Post 原帖

Sorry to answer, but I cannot comment (yet). 很抱歉回答,但我无法评论(还)。

I suffer from the same problem, even worse that on OS X the WWW-Authenticate parameter is lower-cased on every restart of CouchDB and therefore not recognized any more. 我遇到了同样的问题,更糟糕的是,在OS X上,WWW-Authenticate参数在每次重启CouchDB时都是较低的,因此不再被识别。 Therefore it has to be set after EACH restart using Futon/Fauxton or the API. 因此,必须在每次重启后使用Futon / Fauxton或API进行设置。

You could try and play with the next parameter (see http://docs.couchdb.org/en/1.6.1/api/server/authn.html ). 您可以尝试使用下一个参数(请参阅http://docs.couchdb.org/en/1.6.1/api/server/authn.html )。 In principle you send your auth-request to (example in angular2): 原则上你发送你的auth请求(例如在angular2中):

// assuming you bootstrapped HTTP_PROVIDERS and injected Http

// configure headers
let headers: Headers = new Headers()
headers.append('Content-Type', 'application/json')
headers.append('Accept', 'application/json')
headers.append('Authorization', 'Basic ' + window.btoa(username + ':' + password))

// using the injected Http instance
this.http
// post to _session specifying next and the redirect
.post(
  'http://localhost:5984/_session?next=/successfullyLoggedInPage'
  , JSON.stringify({'name': username, 'password': password})
  , {headers: headers}
)
.map((res: Response) => res.json())
.subscribe(
  (res) => {
    // successful auth
  },
  (err) => {
    if (err.status === 401) // failed auth
  }
)

In my setup the web-app and CouchDB are served from two different origins. 在我的设置中,web-app和CouchDB来自两个不同的起源。 I can only get this working if I disable web-security in Chrome due to cross-origin restrictions. 如果由于跨域限制而禁用Chrome中的网络安全性,我只能使用此功能。 I believe a reverse proxy could rewrite the redirect response, eg using nginx's proxy_redirect ( http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect ). 我相信反向代理可以重写重定向响应,例如使用nginx的proxy_redirect( http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_redirect )。

I believe the best solution is to modify the response headers by a reverse proxy. 我认为最好的解决方案是通过反向代理修改响应头。 For nginx there is a module called ngx_headers_more (see https://github.com/openresty/headers-more-nginx-module#readme ) which should be able to do this. 对于nginx,有一个名为ngx_headers_more的模块(参见https://github.com/openresty/headers-more-nginx-module#readme )应该能够做到这一点。 One could check for 401 responses and then modify the header from Authentication: Basic to Authentication: Other, therefore disabling the modal. 可以检查401响应,然后将标头从Authentication:Basic修改为Authentication:Other,从而禁用模式。 In principle Futon/Fauxton should still work then, no? 原则上,Futon / Fauxton还应该工作,不是吗? I haven't tried this approach yet but in the location block of nginx you need to specify 我还没有尝试过这种方法,但是在nginx的位置块中你需要指定

more_set_headers -s 401 'WWW-Authenticate: Other realm="App"'

I hope someone more qualified can add his/her two cents. 我希望更有资格的人能加上他/她的两分钱。

I was having more or less the same problem. 我或多或少有同样的问题。 Though I am using a reverse proxy with the 'proxy' authentication handler of CouchDB. 虽然我使用反向代理与CouchDB的'代理'身份验证处理程序。 When the user tries to do something that he is not allowed to (creating a DB while he is not an admin), a 401 response was returned by CouchDB, triggering HTTP basic auth. 当用户尝试执行他不允许的操作(在他不是管理员时创建数据库)时,CouchDB返回401响应,触发HTTP基本身份验证。 Not so nice, as the reverse proxy handles authentication based on X509 client certificates. 不太好,因为反向代理处理基于X509客户端证书的身份验证。 I actually think that CouchDB should return a 403 response, but that's a different discussion. 我实际上认为CouchDB应该返回403响应,但这是一个不同的讨论。

To fix it, I used your answers, but I am not so eager to use an external Nginx module (ngx_headers_more) and actually am not so fond of changing the header to a 'nonsense' value. 为了解决这个问题,我使用了你的答案,但我并不急于使用外部Nginx模块(ngx_headers_more),实际上我并不喜欢将标题更改为'废话'值。 Instead, with the existing proxy module in Nginx, you can just remove the WWW-Authenticate all together: 相反,使用Nginx中的现有代理模块,您可以一起删除WWW-Authenticate:

proxy_pass              http://${COUCHDB_HOSTNAME}:${COUCHDB_PORT};
proxy_hide_header       WWW-Authenticate;

Seems to be working fine. 似乎工作正常。 See https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header for its documentation. 有关其文档,请参阅https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_hide_header

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM