Introduction to CouchDB with .NET part 24: cookie based authentication for the CouchDB HTTP API

Introduction

In the previous post we looked at role-based authorisation in CouchDB. With roles it’s easier to assign users as database admins, database members and read-only users than working with names only. It’s enough to assign each CouchDB user to a role and the existing authorisation rules will be applied automatically.

In this post we’ll look at how authentication works for the HTTP API using cookies.

Logging in

Using the CouchDB HTTP API with a cookie follows the same model as many popular public APIs out there. We first have to authenticate ourselves using an endpoint. This is analogous to logging in using a form on a UI. The HTTP API responds with an authentication cookie which must be attached to each subsequent HTTP request. The cookie is by default valid for 600 seconds, i.e. 10 minutes. This value can be adjusted in the configuration file, i.e. either default.ini or local.ini. The setting is called “timeout” in [couch_httpd_auth] section:

timeout = 600 ; number of seconds before automatic logout

Cookies can also be made persistent using the following setting in the same section:

allow_persistent_cookies = false ; set to true to allow persistent cookies

We log in using the POST /_session endpoint and send the username and password in the JSON body. We also need to set the Content-Type header to applications/json:

POST http://localhost:5984/_session

Here’s the payload:

{
	"name": "olivia",
	"password": "secret"
}

You can probably guess what the properties in the JSON object stand for.

Since we’re sending our credentials in plain text it’s a good idea to set up HTTPS for our CouchDB server. This guide shows you how to do it.

If the login was successful then the API will respond with some user authentication details:

{
    "ok": true,
    "name": "olivia",
    "roles": [
        "database-read-write"
    ]
}

There will also be a header called Set-Cookie with a value similar to the following:

Set-Cookie: AuthSession=b2xpdmlhOjU5NTI4OUNBOomEzugg8rzgACqaIWWIY4qLjEyB; Version=1; Path=/; HttpOnly

The long string assigned to AuthSession, i.e. b2xpdmlhOjU5NTI4OUNBOomEzugg8rzgACqaIWWIY4qLjEyB in this example, is the cookie itself which must be attached to all subsequent requests. We assigned Olivia to the role “database-read-write” in the previous post and added that role to the database members of the restaurants database. This value must be added as the Cookie header in the request:

Cookie: AuthSession=b2xpdmlhOjU5NTI4OUNBOomEzugg8rzgACqaIWWIY4qLjEyB

Olivia can now execute the following GET request:

http://localhost:5984/restaurants/

The API should respond with summary JSON about the restaurants database.

If, on the other hand, she tries to access the bands database where we set up name-based authorisation she’ll get the following exception in the API response:

{
    "error": "forbidden",
    "reason": "You are not allowed to access this db."
}

Getting the current session data

The _session endpoint can be used to get information about our current session:

GET http://localhost:5984/_session

We’ll get some basic user related information in the current session:

{
    "ok": true,
    "userCtx": {
        "name": "olivia",
        "roles": [
            "database-read-write"
        ]
    },
    "info": {
        "authentication_db": "_users",
        "authentication_handlers": [
            "cookie",
            "default"
        ],
        "authenticated": "cookie"
    }
}

If there’s no valid authenticated session then the user context is null:

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

Logging out

We can also log out from the session. It is the same endpoint and Cookie header as above but the HTTP verb is delete:

DELETE http://localhost:5984/_session

CouchDB will simply respond with an ok true or false:

{
    "ok": true
}

Other types of authentication

The simplest authentication type in any application is basic auth. The username and password are concatenated with a colon in between and transformed into a base 64 string. E.g. the username “olivia” and password “secret” are combined into olivia:secret and then converted: b2xpdmlhOnNlY3JldA== . This authentication type for APIs is nowadays considered highly unsafe and outdated since the base64 string can be easily converted back. This online resource lets you convert the string to base 64 and back.

Nonetheless, CouchDB supports basic authentication. We need to attach the base64 authentication information in the Authorization header of every request we send to the API:

Authorization: Basic b2xpdmlhOnNlY3JldA==

OAuth is on the other hand a much safer way to open a session with an API. It allows the caller to communicate with an API without sharing the username and password in any form. However, it’s also more difficult to demo in a simple HTTP client since the process involves signing the request. You can find an example here on how to set up OAuth with CouchDB.

The require_valid_user key

Finally we can mention that there’s a setting in the CouchDB configuration file which helps close off access for unanimous users. It is under the [couch_httpd_auth] section and is called require_valid_user and is by default set to false. Set it to true to restrict access to the database.

Read the next post here where we see how to connect to CouchDB from C#.

You can view all posts related to data storage on this blog here.

Advertisement

About Andras Nemes
I'm a .NET/Java developer living and working in Stockholm, Sweden.

One Response to Introduction to CouchDB with .NET part 24: cookie based authentication for the CouchDB HTTP API

  1. Pingback: CouchDB Weekly News, July 13, 2017 – CouchDB Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: