Add REST, CORS and authentication to MongoDB

Summary
This blog describes One simple approach to access MongoDB using REST, CORS (Cross-Origin-Resource-Sharing) and with simple authentication and authorization.

Background
This mini-project started because I wanted a way for our in-house projects to share database and be accessible from javascript and at the same time solve the ‘in-house project time-to-market (really fast == now)’ requirement (and of course also to push the work to client developers so I can do other things…).

I was first looking at mongolab.com but I did not feel that I wanted to use yet another external service for such small project(s). Instead I found sleepy.mongoose which seems to be the official MongoDB REST interface and it was really fast to get up and running. But to make it useful even for a small inhouse project (external website though) I was missing some things.

Requirements

  • A single server must be able to serve multiple sites so a javascript client must be able to access the server running on another host and/or port than it origins from. I do not want to setup any proxies like nginx just for this
  • Basic authentication
  • Simple database/collection based authorization

To solve these problems I decided to create a proxy I had tried node.js before so I knew that the proxy part would be really easy and I expected that basic-auth should be really easy to solve as well. To solve cross-origin requests I thought that jsonp was the answer but Anders Janmyr introduced me to CORS and suggested that I should try to solve it that way instead.

Cross-Origin-Resource-Sharing
Cross-Origin-Resource-Sharing is a way for a server to simply say that ‘Hey, I approve cross-origin requests from these hosts (or all) and I accept these methods etc’. Implementing this was really easy and the code below shows all that is needed works (not sure if the Access-Control-Allow-x headers have to always be set or only when OPTION is sent but I had some issues with this). Replace the * with your real hosts.

Authentication and authorization

For authentication I simply use basic-auth which is really easy to implement but I think that you can probably find a library that makes it a little nicer than my hardcoded solution. Authentication is also very simple with a json file containing username, password, database and collection. Checkout the authentication/authorization code for details about this.

Javascript API
For simplicity, there is a javascript api that simply wraps an ajax request. This example finds all documents with name:johan and sorts it by age asc.

The lab project can be found at https://github.com/jayway/mongo-http-proxy

This Post Has 12 Comments

  1. Jay,
    Awesome post, very interesting, time-saver.
    On last step when I issue this command: ./bin/mongo-http-proxy -p 8000 -h localhost – t 27080
    It throws error: mongo-http-proxy command not found.
    Any help is greatly appreciated.
    Tejas

  2. Hi, there should not be any problems. Do you run it from the mongo-http-proxy directory. What platform are you on? Do you have the file mongo-http-proxy/bin/mongo-http-proxy?

    /Johan

  3. Johan,
    I use Ubuntu 12.04. Yes, I have directory structure setup this way; mongo-http-proxy/bin/ and I have mongo-http-proxy file in bin folder.
    Thank you for quick response.
    Tejas

  4. Do you have node.js installed? Is ./bin/mongo-http-proxy executable? You can try run node lib/proxy.js and see if it starts (uses default settings).

    1. Rather than filtering out bad charrcteas in keys or validating good charrcteas in keys, the best approach is to always pick out all and only the fields you want. Never just load a whole array from the user into your database. You can do it in a one-liner with array_intersect_keys, or you can write yourself a little utility function to make it prettier and maybe stringify your values, too.

  5. Johan,
    Thank you, for awesome post and your guidence.
    As you advised, I am able to mannualy start proxy using js engine. However, I was expecting that I will be able to resolve issue of cross domain calls from javascript client. I am still not able to figureout; how I can do that, any help is much appricieated.
    Tejas

  6. Johan,
    Do you have xexample javascript client code?
    Regards,
    Tejas

  7. I am trying to do post and here is how I am trying to do that:

    Mongo Rest Post

    MONGO DATA FROM REST

    base64.settings.ascii = true;
    var auth = this.make_base_auth(‘mbuser12’, ‘brixmedia01’);
    // jQuery
    $.ajax({
    url: ‘http://userprofiles1.cloudapp.net:8000/users/users/_insert?’,
    method: ‘POST’,
    data: ‘[{ “_id” : “o8edb11bf2748072134017d66f8fabe1”, “age” : 29, “gender” : “f”, “cosmetics” : 1, “prada” : 1, “profesion” : “student” }]’,
    beforeSend: function (req) {
    req.setRequestHeader(‘Authorization’, auth);
    }
    });
    function make_base_auth(user, password)
    {
    var tok = user + ‘:’ + password;
    var hash = base64.encode(tok);
    return “Basic ” + hash;
    }

  8. Looking at client api example, it appeared that it only works for GET. Since, I wanted to do POST, I used this method.

  9. It should work for POST as well.
    EDIT-
    Sorry about that, of course it does not work but it is a really small change to add post.

Leave a Reply

Close Menu