How Do Popular Apps Authenticate User Requests from Their Mobile App to Their Server

Identify mobile application

If you need to make secure HTTP calls (webservice API) from a mobile app (a native compiled app), you can try the following approach:

Edit: This approach assumes that you can't rely on the user operating the app for authentication purposes (because then you could simply ask the user to type in a secure password in the app).

  1. Assuming you are implementing the app, save some sort of secret API key in the code.

  2. When the app makes an API call via HTTP, it will always be done using HTTPS (so everything is encrypted).

  3. The app will send the secret API key as a URL parameter.

  4. The server will authenticate by checking if the secret key is correct.

Sniffing the app traffic will not reveal the secret key (because of the HTTPS).

You are mostly vulnerable to someone reverse-engineering your app to discover the secret key inside. This can be made tough by using various obfuscation and anti-debugging techniques, but cannot be made truly impossible. As long as you're using a compiled language (like Objective-C, not JS for a web-app) this will already be tough without any special games. If you avoid placing your API key string as-is and compute it using some short code in the app, you've made it about 1000 times tougher to discover.

Without knowing more about your specific problem, it's hard to suggest alternate approaches. Please give more details if you are looking for something different.

how can I authenticate a user from a web app to an API?

(If you don't want to read, the list bellow sum up the whole idea)

A possible solution (tell me if I'm wrong) would be to display the login form in the consumer (web apps, mobile apps, etc), the user click on it's provider (myopenid, google, etc) that opens a popup to do the login.
The tricky part is that the return_to parameter would be set to the API, not the website

The API will then resend the check_authentication and get the is_valid:true (or not).
During this step, the app would query the api to a specific url that return the state of the authentication (processing, failed, success). While it's procesing, an indicator is displayed to the user (loading gif), and if it's success/fail the result is displayed to the user.

If the api receive a is_valid:true, then it will ask informations about the user to the openid server, like email, firstname, lastname, and compare them with it's user's database. If there is a match, the api create a session between itself and the app, if the user is new, it create a new entry and then the session.

The session would be a unique token with a specific duration (maybe equal to the openid server assoc_handle duration ?)

It seems to be something possible, but I'm not an expert in security.

In order to explain things simplier, here is a little "map" :

Note: Provider is the OpenId server (that provide the informations about the authentication)

  • The User go the webapp and click on the login icon of his provider (Google for ex)
  • The webapp opens a popup containing the provider login page and access page, and specify a return_to to the Api
  • The provider sends informations to the Api
  • The Api validate these informations via the check_authentication
  • If not valid, the API indicate to the webapp (that ask the api every x seconds) the failure
  • If valid, the Api asks informations about the user to the provider, like email, display name, etc
  • If the user exists, a session is created
  • If the user is new, he's added to the database and the session is created
  • The Api returns the state of the auth (in this case, success) with a token session that will be used by the web app for further requests.

How to manage Authentication/Authorization for user requests sent from native mobile apps calling Play2!-Scala REST services

Ok, this is for authentication, then the login is separate, you can use your own system or something like openID, etc.
The problem is how to store that the user is authenticated.

The main idea for securing your REST service would be to use an auth token that is signed on the server side with some identifier of the user.
It would go this way:

  1. the user enters a id/password
  2. a rest method checks this and if it's valid, sends a token back to the phone. You store that in your app
  3. every time you make a call to your rest API you send the user id and the token and you check the token on the server.

You have two solutions for generating and checking tokens:

  1. The token is basically the user id, concatenated with some salt of your own (whatever secret message you want) and then signed with a private key on your server. Personally I have done this with HMAC-SHA256 (using javax.crypto in my scala code).
    If someone tries to use your REST API, they won't be able to generate the token as they do not know your private key nor the secret.
    Every time you receive a request on your REST API (3), you just recompute the hash and compare it with the one you were sent as a token.
  2. Instead of a HMAC with the user ID, another solution is to store a random number in your database for each user. This will be your token.
    Every time you receive a request, you check in the database the secret token for that user and see if it's the same as the one from the query.

This will create infinite tokens, so your user will never be logged out, you can add an expiration date to these solutions quite easily:

  1. if using HMAC, you put in your token (before signing) the current date. For instance, if you want a 24h session, you can do something like:

    val format = new SimpleDateFormat("d/M/yyyy");  
    isoFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
    val date = format.format(new Date());
    val token = calculateHMAC(userID + date + secret);

    for shorter/longer periods, you change the format to include more or less so that every time you generate the token to check it you fall in the same period.

  2. for the random number/database solution, you just store the date of creation of the random token, and you see if it's in the period you like.

If you are using an OpenID (or similar) identification from a third party, you will have to show a WebView to the user where you load the openID provider's page, you just have to make sure that the redirect page after the authentication contains a generated token hidden somewhere (in the title for instance) and you extract it with your app code.

This is pretty straightforward to implement yourself, but I have seen a plugin for play2 to deal with token auth:
https://github.com/orefalo/play2-authenticitytoken (never used personaly)
and one for stateless auth:
https://github.com/blendlabs/play20-stateless-auth

For the loggin bit, you don't have to implement that, there are good modules out there for play:

  • https://github.com/joscha/play-authenticate
  • https://github.com/jaliss/securesocial


Related Topics



Leave a reply



Submit