0

I'm currently developing an app mainly for learning purposes. Everything I have read so far has confused me rather then help. My goal is to connect to a MySQL database and retrieve data. The database consists of quotes, authors, and a category that the quote belongs to.

I know PHP and MySQL enough to write an API to return JSON data form the server. I think I understand that the Android app needs to send a JSON encoded POST request. So I'm thinknig this makes it possible for anyone to decompile the app and see the API url's and similarly generate requests and retrieve data from the database.

My main concern is, how can I generate the requests from Android to talk to the server API in a secure way, and verify that the request is coming from the app.

Thanks for reading!

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
xsorifc28
  • 5,112
  • 6
  • 16
  • 24

1 Answers1

2

If I understand your question correctly, you know how to do the POST in Android, but you want a "secure" way to do it. I think what you are looking for is a basic method of authentication.

The simplest way is to have a user log in with username/password (which the username can be stored in SharedPreferences or some other manner). As one user has pointed out, there ARE concerns regarding storing of passwords in SharedPreferences, though multitudes of other answers here and apps use this method of storage for it - just using the password ONCE would work until the token expires. The server app would provide this token after the first successful authentication. You'd have to track to tokens in your database and assign an expiry date to them for better security. All of this should ONLY be performed over SSL, so the POST payloads are encrypted.

Decompiling an app and figuring out an API endpoint from a request are two totally different things. For your situation, you don't have to really worry about obscuring your endpoints, only securing the POST (JSON) payload and providing a simple method of authorization. Your endpoints are going to be probed regardless, so it is best to simply put authentication mechanisms in place so only those users authorized will see the data.

Creating a Sync Adapter would help in managing all of the authentication work, and the user's USERNAME (and the token) could be saved relatively safely in Shared Preferences. You would have to, however, set up this username/password/token authentication system on your server. Here is an example process flow:

User [username/password] -> Server [authentication] -> Server [token] -> User [store token]

Then, after that, the app will authenticate against the endpoint with their token until it expires (the server will notify the app when it expires):

User [token] -> Server [validates token] -> User [data] -> Server [data]

The token could be something as simple as a random GUID.

This will ensure the user is authorized to receive the data and should ONLY be performed through a POST request and ONLY over SSL to ensure the JSON payload is as secure as possible from prying eyes. You can go into a whole bunch of other areas here, such as rate-limiting requests to prevent people bombarding your APIs with brute-force attacks or something else, but that would all be done on the server side.

Granted, this is NOT the most secure way to do this, as there are better protocols like OAuth, but they are also much more complex to implement for a simple client/server app. I would highly recommend you investigate them, however.

Sources:

Creating a Sync Adapter: http://developer.android.com/training/sync-adapters/creating-sync-adapter.html

How to do an HTTP POST in Android: How to do a HTTP Post in Android?

PHP GUID: http://php.net/manual/en/function.com-create-guid.php

Community
  • 1
  • 1
Michael Hawkins
  • 2,793
  • 1
  • 19
  • 33
  • 1
    Do not store a password in shared preferences. If the user ever loses the phone, they've lost the password. It will be read. If they used that password elsewhere, everyplace they used it is compromised. In addition, you've permanently lost this account because with the password they can change your password. The correct way to do this is to send the password up to the server once, and receive a login token back. Store that in shared preference and send it up with each request. If that token is compromised, nothing else is lost. – Gabe Sechan Jul 27 '14 at 01:59
  • Really? A downvote for that? I personally know of a dozen open source apps using that methodology, though I may not agree with it myself, plus there are dozens and dozens of answers here that show examples for doing the same thing. Regardless, I have updated my answer to reflect these concerns and I think the whole downvote for that one part is wholly unnecessary - I took the time to do the answer, a simple comment would have sufficed. The whole downvote for something so simple makes people not want to even bother writing an answer - you could have just pointed it out in your comment. – Michael Hawkins Jul 27 '14 at 02:05
  • Show me the other exammples on here of doing that and I will (and have been) downvote them as well. The idea here is that we want to help people become better programmers and improve things. Telling people to use an insecure method only makes the problem worse. – Gabe Sechan Jul 27 '14 at 02:18
  • As I've said, the answer has been updated. Here ya' go: http://stackoverflow.com/questions/9233035/best-option-to-store-username-and-password-in-android-app , http://stackoverflow.com/questions/785973/what-is-the-most-appropriate-way-to-store-user-settings-in-android-application , http://stackoverflow.com/questions/19629625/best-place-for-storing-user-login-credentials-in-android , http://stackoverflow.com/questions/1925486/android-storing-username-and-password ... there are many, many more and some have hundreds of upvotes. – Michael Hawkins Jul 27 '14 at 02:31
  • One of those posts said it was a bad idea and not to do it at all, I'm ok with that. The others have been downvoted. If you see any more let me know. – Gabe Sechan Jul 27 '14 at 02:32