CouchDB login for Cloudant

von

Cloudant is built with CouchDB code; that’s no secret. IBM added some of their spice to the project, which they want to contribute back at some time. However, when you try to create a session with modern CouchDB approaches, you will fail. Cloudant says it’s current version is CouchDB 1.0.2. And that’s causing some pain.

The main difference is, Cloudant does not support server side hashing of passwords. With CouchDB, you can add a user by just saying: here is my password! And CouchDB adds some salt, hashes your password and hey, you are safe. Older CouchDB leaves that salting and hashing to the user.

That is still the case with Cloudant if you want to use CouchDBs authentication layer. Cloudant provides it’s own authentication layer. In some cases, you want to use Cloudant and CouchDB in conjunction, and of course it makes sense to have a single implementation for authentication too.

Let’s fix that by bypassing the Cloudant authentication layer.

We first need to disable the custom layer to use the CouchDB _users database. You can find some information how to do that deeply buried on the CloudAnt pages. To be honest, I found this more confusing than helpful. Here is what I did:

curl -X PUT -d '{
  "couchdb_auth_only": true
}' "https://<cloudant-user>:<cloudant-pass>@<your-project>.cloudant.com/<your-database>/_security"

By PUT’ting:

{
  "couchdb_auth_only": true
}

I can disable Cloudants authentication layer. While the docs speak of additional parameters, I did not need them.

Let’s create a new user:

curl -X PUT -H "Content-Type: application/json" -d '{
  "password_sha": "329983971fc5dc8d157ccb10f2c0e71d5725cfff",
  "salt": "638769a280f1c46b18707e9db3edf844",
  "roles": ["my-role"],
  "type": "user"
}' "https://<cloudant-user>:<cloudant-pass>@<your-project>.cloudant.com/_users/org.couchdb.user:test5"

I PUT this JSON to: /_users/org.couchdb.user::

{
  "password_sha": "329983971fc5dc8d157ccb10f2c0e71d5725cfff",
  "salt": "638769a280f1c46b18707e9db3edf844",
  "roles": ["my-role"],
  "type": "user"
}

The salt should be generated randomly. With PHP, you could do it like:

$salt = uniqid(mt_rand(), true);

Then you need to hash and salt the password. This is done by making the salt a suffix of the password and then hashing it.

$password_sha = sha1($password . $salt)

Basically that’s it. What you need to do now is to create a session:

curl -X POST https://<your-project>.cloudant.com/_session -d 'name=test5&password=test4'
{"ok":true,"name":"test5","roles":["my-role"]}

From this point, cookies take over.

Credits

Tags: #couchdb #nosql #cloudant

Newsletter

ABMELDEN