16
votes

I'm planning on using CouchDB's built-in cookie authentication for my app (note that this isn't a CouchApp, I'm using a web server between my client and db).

So when a user first logs in with their credentials:

  • Credentials are sent to CouchDB from web client via web server
  • CouchDB authenticates credentials and returns a Set-Cookie header
  • This header is sent to the web client and means that all subsequent requests for database operations just pass on the Cookie header to CouchDB via the web server.

Whilst I've been able to ascertain that:

You can keep using [the cookie] token for 10 minutes by default. After 10 minutes you need to authenticate your user again. The token lifetime can be configured with the timeout (in seconds) setting in the couch_httpd_auth configuration section.

It isn't clear to me if this 10 minute period is (or can be set to be) a sliding window.

By this I mean; if the user continues to use the application for the whole 10 minutes (sending the cookie along on each request), will the cookie automatically be re-set (in a similar way to FormsAuthentication cookies in .NET) until a period of in-activity for 10 minutes?

References used

1

1 Answers

33
votes

For a browser, the (configurable) 10-minute period is a sliding window. Every time CouchDB responds to a request, it will update the cookie to a new value, effectively refreshing the login.

For a client, you must remember to reset the cookie value when you see a Set-Cookie header (or pass it through to your own client in your case).

For example, I have a short timeout (30 seconds):

$ curl http://admin:admin@localhost:5984/_config/couch_httpd_auth/timeout
"30"

Next I will:

  1. Log in
  2. Wait a little while
  3. Check my session with the cookie, before the timeout
  4. Wait for the timeout
  5. Check my session with the cookie again, after the timeout
  6. (Quickly) check my session with the new cookie CouchDB set in step 3

Notice that the first confirmation has {"name":"me"} (I am logged in); the second has {"name":null} (I am logged out); but the third has {"name":"me"} again (I am still logged in due to using the updated cookie).

$ curl -X POST -i localhost:5984/_session -d name=me -d password=secret
HTTP/1.1 200 OK
Set-Cookie: AuthSession=bWU6NEY5QjQ3QTA6Ao6zetUZUxkno37ULd2qdRRjmsc; Version=1; Path=/; HttpOnly
Server: CouchDB/1.2.0 (Erlang OTP/R15B)
Date: Sat, 28 Apr 2012 01:28:00 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 35
Cache-Control: must-revalidate

{"ok":true,"name":"me","roles":[]}

$ sleep 20

$ curl -i localhost:5984/_session -H Cookie:AuthSession=bWU6NEY5QjQ3QTA6Ao6zetUZUxkno37ULd2qdRRjmsc
HTTP/1.1 200 OK
Set-Cookie: AuthSession=bWU6NEY5QjQ3QkM6WonDdsAdO8p7QUlLWCZQXVAfcvU; Version=1; Path=/; HttpOnly
Server: CouchDB/1.2.0 (Erlang OTP/R15B)
Date: Sat, 28 Apr 2012 01:28:28 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 165
Cache-Control: must-revalidate

{"ok":true,"userCtx":{"name":"me","roles":[]},"info":{"authentication_db":"_users","authentication_handlers":["oauth","cookie","default"],"authenticated":"cookie"}}

$ sleep 10

$ curl -i localhost:5984/_session -H Cookie:AuthSession=bWU6NEY5QjQ3QTA6Ao6zetUZUxkno37ULd2qdRRjmsc
HTTP/1.1 200 OK
Server: CouchDB/1.2.0 (Erlang OTP/R15B)
Date: Sat, 28 Apr 2012 01:28:43 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 140
Cache-Control: must-revalidate

{"ok":true,"userCtx":{"name":null,"roles":[]},"info":{"authentication_db":"_users","authentication_handlers":["oauth","cookie","default"]}}

$ curl -i localhost:5984/_session -H Cookie:AuthSession=bWU6NEY5QjQ3QkM6WonDdsAdO8p7QUlLWCZQXVAfcvU
HTTP/1.1 200 OK
Set-Cookie: AuthSession=bWU6NEY5QjQ3RDA69pqrNVd-ClZ7_v4SkcghdZRRhCs; Version=1; Path=/; HttpOnly
Server: CouchDB/1.2.0 (Erlang OTP/R15B)
Date: Sat, 28 Apr 2012 01:28:48 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 165
Cache-Control: must-revalidate

{"ok":true,"userCtx":{"name":"me","roles":[]},"info":{"authentication_db":"_users","authentication_handlers":["oauth","cookie","default"],"authenticated":"cookie"}}

In CouchDB 1.2.0 and later, you can set _config/couch_httpd_auth/allow_persistent_cookies to "true" and it makes things easier to see. The cookie will have an obvious "Expires" flag which you can see is always set to the current time plus your timeout value.