2

I posted this question on DBA, but it got closed and was never reopened even after I rewrote the whole thing to be more specific. I think its more appropriate for programmers anyway :)

Background Information

I have a CouchDB server (Server B) that is accessed by another server running PHP (Server A). My web app (Client-side Javascript) makes a request for a file to Server A. Server A sends requests to Server B with the access credentials (username:password). Server B returns JSON objects that correspond to matched files, then Server A returns that data to the client. The response includes some meta data about the file and a URL to the file on Server B. The actual file data itself is not included in the response.

The Problem

The URL to the document attachment included in the JSON response from Server B includes access credentials (username:password). Server A responds to the client-side request by returning those JSON objects.

The client now has this information:

https://username:password@host:port/dbname/path/to/file.whatever

Currently all data contained within Server B resides in one database instance. If the client has access to the username:password to the CouchDB then all data could be queried with those access credentials. Like so,

https://username:password@host:port/dbname/_all_docs

Server-side considerations

CouchDB on Cloudant

Client-side considerations

The Javascript running on the client requires a URL string to the file. The files that are being referenced are KML layers for Google Maps. A new KML layer is created using this constructor.

What I am looking for

Essentially my solution would come if I can provide a link to a CouchDB document attachment without giving the username/password.

https://host:port/path/to/file.whatever

What I did

I had to enable cURL for PHP on Server A.

sudo apt-get install curl libcurl3 libcurl3-dev php5-curl
sudo /etc/init.d/apache2 restart

Got a bit of code from David Walsh's blog.

My Javascript client code gets a list of JSON file meta data from Server A. This data includes unique DB IDs and file names (No passwords or API keys). I then pass the document ID and filename to another service on Server A which echoes the value of,

get_data('https://username:password@Server B:port/dbname/path/to/file.whatever');

I can now serve out the files to the client without revealing username or password for CouchDB on Server B.

cs_brandt
  • 185

2 Answers2

2

I don't think you'll be able to do what you want without opening up all the CouchDB documents to all-comers.

The solution is, I believe, to only send back to the client this portion of the returned document URL:

dbname/path/to/file.whatever

And then keep your client talking with Server A:

https://Server A/get_document/dbname/path/to/file.whatever

Server A then just translates this to the return form Server B:

https://username:password@host:port/dbname/path/to/file.whatever

That way the client never needs to know about Server B, and Server B can be locked down away from prying eyes.

Peter K.
  • 3,818
  • 1
  • 25
  • 34
0

It sounds like you want the documents the end user to receive to be served up directly from the database server. In general, thats a bad idea. Particularly if this is a public facing application. Better to insolate the database they way you have it now. Is there a particular reason you feel that the db needs to directly hand the client the document?

I would keep everything in your middleware application, and have that handle the document delivery. Or if you must, create a separate server application that only handles the document transfer between the client and db. The client would request a document URL, and your app server would fetch it from the db and return it to the client for them.

GrandmasterB
  • 39,412