3

The current solution that I have to adopt uses JDBC and stores the user/password of the database inside the android app. That's as far as I'm concerned not a good solution. I would like to implement a mapping layer on the webserver in the middle.

Is there any best practice or recommended strategy for this? Should I use SOAP or JSON or something completely different (because they're well implemented and/or easy to use in Java)? Are there any mapping tools for postgresql <-> SOAP/JSON/whatever in PHP or will I need to write these scripts by myself?

Any pointers will be greatly appreciated.

Lichtblitz
  • 213
  • 2
  • 10

2 Answers2

9

Quick version:

Use a web service midlayer running on a public host you control (possibly but not necessarily the database host). Expose public web service methods to do the limited work you want to permit and nothing else.

Related questions:

Implementation options

Personally I'd use a Java application server like Apache Tomcat or JBoss AS 7 and I'd write my web service methods using JAX-RS to produce a nice REST-style API for my app to use. That's what I'm familiar with and it works well, but you have lots of options including implementations of:

  • REST-like APIs (Java's JAX-RS impls Jersey and RESTEasy, various other langs tools) that use HTTP requests and produce JSON or XML replies.

  • SOAP with WSDL, the classic "web service" layer. In Java done with JAX-WS among other options. Most languages have tools for SOAP+WSDL but it's kind of crappy to work with especially on intermittently connected devices like mobiles.

  • XML-RPC if you like pain

There are some JAX-RS quickstarts on the JBoss AS 7 quickstarts list; just search for "JAX-RS". The "kitchen sink" quickstart is useful, though perhaps not ideal if you're not familiar with the basics of JBoss AS 7 and Jave EE 6. Fort the JAX-RS specifics you're better off with a Jersey or RESTEasy tutorial like this or this.

Important considerations

Use HTTPs if possible, and if access isn't to be public use a suitable HTTP authentication scheme like HTTP Basic auth over HTTPs. Any decent web services implementation will offer authentication options or support those of the platform on which it runs. Avoid the temptation to implement your own authentication and user management at the web services layer, you will screw it up; use the auth at the HTTP layer that's already written and tested. This may require the use of something like Apache's mod_auth_pgsql, JBoss AS 7's JDBC security realms, etc. The only case I'd consider not doing proper per-user HTTP auth is where I don't need to separate my users for security reasons, I only care that it's my app accessing the server, ie if my security requirements are quite weak. In this case I'd use a fixed username/password for the whole app and possibly an X.509 client certificate if Android supports them.

Remember that no matter how you secure things, all credentials are either known to the user or can be extracted trivially from a .apk so you still have to assume anybody could access your web service methods, not just your app. Write them accordingly.

Do not just send SQL from your app over a web service call to the server and return the results as JSON. This is horrifyingly insecure, as well as ugly and clunky. Write a web service method for each individual task you want the app to be able to perform and keep the SQL in the server. Remember to use parameterised queries and be careful of other SQL injection risks. These web service methods may use one or more queries to produce a single reply - for example, you might collect a "Customer" record and all associated "Address" and "Contact" records then return the result in a nice JSON object the Android device can consume, saving numerous slow and unreliable network round trips.

No matter what you use, make sure to do your web service calls in a background worker thread and not to block the user interface. Be prepared for timeouts and errors, and for the need for retries. Test your app by simulating intermittent connection loss, high latency, and high rates of packet loss and make sure it remains usable.

Community
  • 1
  • 1
Craig Ringer
  • 307,061
  • 76
  • 688
  • 778
  • Thanks for the detailed answer. Many of those points you made were already clear to me but those few that weren't helped out a lot. There's only one thing: why should the API (web service) be password-protected in an environment where we don't differentiate between users? Isn't the whole point of an API that other people may use it in their own way? Or do you prefer to add a discouragement to use the API as another security layer for potentially not yet detected bugs or exploits? – Lichtblitz Jun 06 '12 at 10:43
  • @Lichtblitz Paranoia, mostly. If you don't differentiate between users you're right that there isn't much point, since anyone can extract the credentials from your .apk to use your API directly. – Craig Ringer Jun 06 '12 at 11:27
1

Is there a best practise:

It depends on the person. All have their strength and weakness. I prefer, and I think many but not all will agree on JSON cause it is really easy to use in Android. It's also lightweight and very easy to use in php. Php has methods to convert an array/object to json and back.

It is indeed not recommended to save your postgres data on an android device.

My strategy is usually:

PHP server side with a POSTGRESQL database, using PDO to communicate between my models and the database.

If you are not familiar with PDO(php data objects), I recommend you make yourself familiar with it.

php.net PDO

Android as client, using JSON as method of transfering data from and to.

There are many examples that can help you.

Android has standard libraries to handle json parsing.

See this answer for an example:

example

Community
  • 1
  • 1
Joey Roosing
  • 2,145
  • 5
  • 25
  • 42