Prevent Authentication popup 401 with CouchDB PouchDB

泄露秘密 提交于 2019-12-04 07:29:43

I finally found the solution:

Edit the CouchDB config local.ini and change the HTTP Header sent in response:

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. Changing Basic to anything else makes the browser ignore it and you can deal with the login yourself.

Update 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. Add the following to your 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.

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. Therefore it has to be set after EACH restart using Futon/Fauxton or the API.

You could try and play with the next parameter (see http://docs.couchdb.org/en/1.6.1/api/server/authn.html). In principle you send your auth-request to (example in 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. I can only get this working if I disable web-security in Chrome due to cross-origin restrictions. I believe a reverse proxy could rewrite the redirect response, e. g. using nginx's 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. One could check for 401 responses and then modify the header from Authentication: Basic to Authentication: Other, therefore disabling the modal. In principle Futon/Fauxton should still work then, no? I haven't tried this approach yet but in the location block of nginx you need to specify

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. 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. Not so nice, as the reverse proxy handles authentication based on X509 client certificates. I actually think that CouchDB should return a 403 response, but that's a different discussion.

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. Instead, with the existing proxy module in Nginx, you can just remove the WWW-Authenticate all together:

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!