3007

Secure API for iOS without user account

I know this is a popular type of question, but I haven't been able to find any other questions that address my specific needs.

Background

    <li>I have an iOS app that retrieves data from my Ruby on Rails developed web API.</li> <li>I would like to privatize my API so that other sources cannot use the data coming from my API (ie. someone else develops an app that hits my API url and uses the data for their customers)</li> </ul>

    Requirements

      <li>(HARD) Private API so that only authorized clients (coming ONLY from iOS app) can access the data from the API.</li> <li>(HARD) Users must not have to create user/password accounts.</li> <li>(SOFT) I have read that SSL can become a nightmare when trying to get apps approved by Apple. Since this is a small-time app (as of now), I prefer to not depend on SSL. <strong>However</strong>, if you can point me in the right direction regarding the ease of using SSL with all API traffic on iOS, I am all ears).</li> </ul>

      ! <strong>Skip to the end for the question if you are losing interest :)</strong> !

      Ideas thus far

      Idea 1:

      <ol> <li>iOS requests token from web, sending some UUID</li> <li>WEB responds with API_Token and Token_Expiry</li> <li>WEB stores UUID, API_Token, and Token_Expiry in database</li> <li>iOS stores API_Token, Token_Expiry locally</li> <li>iOS requests data by sending UUID and API_Token</li> <li>WEB verifies UUID and API_Token, responds with data</li> <li>Repeat Steps 5-6 until API_Token expires, then repeat from Step 1</li> </ol>

      *Idea 2: (single use API_Token)*

      <ol> <li>iOS requests token from web, sending some UUID</li> <li>WEB responds with API_Token</li> <li>WEB stores UUID and API_Token in database</li> <li>iOS stores API_Token locally</li> <li>iOS requests data by sending UUID and API_Token</li> <li>WEB verifies UUID and API_Token, responds with data AND NEW TOKEN</li> <li>iOS gets data and saves NEW TOKEN locally</li> <li>Repeat Steps 5-7 indefinitely</li> </ol>

      Problems with these ideas

      I believe there is no perfect UUID solution for iOS any longer. If the UUID can change over time (or if the user has multiple iOS devices), an authentication problem can occur.

      If a hacker gets an API key, I don't want them to be able to access the data (hence the expiry or new token idea).

      Question

      What suggestion do you have to create a secure API between Rails and iOS?

      <hr>

      <strong>EDIT 1:</strong>

      I'm still surprised this isn't something that comes up all the time. There must be a ton of apps out there that communicate to an API but do not force user's to sign up. If SSL or OAuth is the only proper solution, please defend. I'm all ears.

      Answer1:

      Aside from the problem of tracking users across devices, for which I wouldn't know how to provide a reasonably simple and reliable mechanism, other than a Game Center account, let's discuss a simple way of closing your API to other apps.

      The handshake would involve your client submitting a URL request that could already include a device-specific token to identify your user. The response from your server will be a random one-time challenge in form of a string. Both the client and the server know a non-trivial function that generates a response string as a function of the challenge and possibly the user token, thus validating the client.

      The mechanism is by no means secure but is trivial to implement and will provide some barrier to others. You should definitely validate the form of the user token for some additional protection. For example, if your token is a MAC address, the request must have the form of a MAC address.

      Answer2:

      I ended up rolling my own solution based on a few suggestions that I found on the web (see reference links at the end).

      <ol> <li>iOS checks if it has an auth_token. If no, proceed to step 2, else proceed to step 4.</li> <li>iOS requests an auth_token by sending a special signature that only my iOS app and servers know how to generate.</li> <li>WEB validates the special signature and creates a unique auth_token that is saved in the DB and sent back to the iOS app.</li> <li>iOS requests data by sending the auth_token and a generated signature (again one that only my iOS and server know how to generate).</li> <li>WEB validates that the auth_token exists in the DB. It then generates an auth_signature and verifies that the request came from my iOS app.</li> <li>WEB responds with the data and a newly generated auth_token.</li> <li>WEB deletes previous auth_token from DB.</li> <li>iOS saves new auth_token locally and uses data.</li> <li>Repeat steps 4-8; If response is 401 unauthorized, restart at step 1.</li> </ol>

      References:

      This GitHub Gist by @keighl is what started me off, by far the best example that I found: https://gist.github.com/4336694

      Railscast: Securing an API: http://railscasts.com/episodes/352-securing-an-api

Recommend

  • Remove a key-value pair from javax.json.JsonObject
  • Query a table in different ways or orderings in Cassandra
  • Why hadoop_home is not set correctly
  • Capture video without preview
  • SQL select: two-dimensional select with variable column count
  • Iterate Through Folders/Subfolders/Files in Google Drive
  • Sitecore 8: Number of Recipients in List Manager not calculating properly
  • How to change number(7,2) to varchar in oracle?
  • DotNet CLI build fails for VS .NET Core project when run from TFS 2015 build agent
  • How to do a pull request from my current state
  • Xcode when adding localization not all storyboards are found
  • JPanel error - J Component cannot be resolved
  • How do I get sun webserver to redirect from /
  • How to save R plot image to database?
  • Parallel Computing - Shuffle
  • Setting up IntelliJ Idea remote debugging with XDebug
  • How to personalize a timeline with R?
  • TelephonyManager crashing on android studio
  • Drawing rotated bitmaps on canvas
  • Changing Machine Type on Google Cloud
  • How do I get an Option instead of an Option from a Diesel query which only returns 1 or 0 records?
  • ASP Error 0223 - TypeLib Not Found, intermittent, resolved after IIS restart
  • Applicative Laws for the ((->) r) type
  • Unable to run app-client that is accessing an EJB on GlassFish v3
  • How do you compute the XOR Remainder used in CRC?
  • Socket io in node app on google app engine
  • Migrating from java 1.4 ,EJB 1 to Java 6 and EJB 3 [closed]
  • Can I use jquery to blank textarea fields or ajax like input boxes?
  • SQL Server Cascading
  • How to count amount of elements in a row of a matrix in C
  • Is there an HTML code that can make my background picture transparent and my text non-transparent?
  • How to get google-services.json from Developer console?
  • Run script file on remote server
  • How do I import an existing Grails 3 (3.0.12) project in IntelliJ 15
  • Examples of how to a STS in .Net 4.5 using WCF
  • android google indoor map
  • Sequential (transactional) API calls in angular 4 with state management
  • Access Android Market through SSH tunnel
  • Is there a perl module to validate passwords stored in “{crypt}hashedpassword” “{ssha}hashedpassword
  • Make VS2015 use angular-cli ng at build time in a .NET project