Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it good practice to give each CouchDB user a separate database?

I have a bit of conceptual question regarding the structure of users and their documents.

Is it a good practice to give each user within CouchDB their own database which hold their document?

I have read that couchDB can handle thousands of Databases and that It is not that uncommon for each user to have their database.

Reason:

The reason for asking this question is that I am trying to create a system where a logged in user can only view their own document and can't view any other users document.

Any suggestions.

Thank you in advance.

like image 675
Skywalker Avatar asked Feb 16 '15 09:02

Skywalker


4 Answers

It’s rather common scenario to create CouchDB bucket (DB) for each user. Although there are some drawbacks:

  • You must keep ddocs in sync in each user bucket, so deployment of ddoc changes across multiple buckets may become a real adventure.
  • If docs are shared between users in some way, you get doc and viewindex dupes in each bucket.
  • You must block _info requests to avoid user list leak (or you must name buckets using hashes).
  • In any case, you need some proxy in front of Couch to create and prepare a new bucket on user registration.
  • You better protect Couch from running out of capacity when it receives to many requests – it also requires proxy.

Per-doc read ACL can be implemented using _list functions, but this approach has some drawbacks and it also requires a proxy, at least a web-server, in front of CouchDB. See CouchDb read authentication using lists for more details.

Also you can try to play with CoverCouch which implements a full per-doc read ACL, keeping original CouchDB API untouched, but it’s in very early beta.

like image 122
ermouth Avatar answered Sep 23 '22 11:09

ermouth


This is quite a common use case, especially in mobile environments, where the data for each user is synchronized to the device using one of the Android, iOS or JavaScript (pouchdb) libraries.

So in concept, this is fine but I would still recommend testing thoroughly before going into production.

Note that one downside of multiple databases is that you can't write queries that span multiple database. There are some workarounds though - for more information see Cloudant: Searching across databases.


Update 17 March 2017:

Please take a look at Cloudant Envoy for more information on this approach.

Database-per-user is a common pattern with CouchDB when there is a requirement for each application user to have their own set of documents which can be synced (e.g. to a mobile device or browser). On the surface, this is a good solution - Cloudant handles a large number of databases within a single installation very well. However ...

Source: https://github.com/cloudant-labs/envoy

like image 22
Chris Snow Avatar answered Sep 22 '22 11:09

Chris Snow


The solution is as old as web applications - if you think of a mySQL database there is nothing in the database to stop user B viewing records belonging to user A - it is all coded in the application layer.

In CouchDB there is likewise no completely secure way to prevent user B from accessing documents written by user A. You would need to code this in your application layer just as before.

Provided you have a web application between CouchDB and the users you have no problem. The issue comes when you allow CouchDB to serve requests directly.

like image 27
Ewan Makepeace Avatar answered Sep 20 '22 11:09

Ewan Makepeace


Using multiple database for multiple users have some important drawbacks:

  • queries over data in different databases are not possible with the native couchdb API. Analysis on your website overall status are quite impossible!
  • maintenance will soon becomes very hard: let's think of replicating/compacting thousands of database each time you want to perform a backup

It depends on your use case, but I think that a nice approach can be:

  1. allow access only through virtual host. This can be achieved using a proxy or much more simply by using a couchdb hosting provider which lets you fine-tune your "domains->path" mapping

  2. use design docs / couchapps, instead of direct document CRUD API, for read/write operations

    2.1. using _rewrite handler to allow only valid requests: in this way you can instantly block access to sensible handlers like _all_docs, _all_dbs and others

    2.2. using _list and _view handlers for read doc/role based ACLs as described in CouchDb read authentication using list

    2.3. using _update handlers for write doc/role based ACLs

    2.4. using authenticated rewriting rules for read/write role based ACL.

    2.3. filtered _changes handler is another way of retrieving all user's data with read doc/role based ACL. Depending on your use case this can effectively simplify as much as possible your read API, letting you concentrate on your update API.

like image 44
giowild Avatar answered Sep 22 '22 11:09

giowild