Android is experiencing a rapid growth. From the device that handled emails, texts and calls it expanded to a device that can do almost all work that computers did. Our everyday work now can be done on almost every portable device - however many of us experienced problems with web application UX on mobile devices. That obviously lead to native ports of web clients.
But what if we are developing a web application along with a mobile client?
One of the best tandems for such work is combining Google App Engine as our target platform and Android as client. Knowing that almost every Android user has Google Account and having SSO for free seems like a big advantage.
This article covers how to configure, authenticate and perform authorized requests to Google App Engine application from Android application using Google Accounts API.
Overview
Authentication against Google App Engine using Google Accounts API is done by accessing Google Account (which was added in Android) and use it’s token to get authentication cookie.
Authentication is done in the following steps:
- Obtain authentication token from the Google Account,
- Use that token to retrieve authentication cookie from Google App Engine,
- Use authentication cookie in every request made further.
Tokens by default expire after 24 hours. On expiration you should invalidate token, obtain new one and request new authentication cookie for further requests.
Invalidating token is done in the following steps:
- Obtain authentication token from the Google Account,
- Invalidate that token,
- Obtain newly generated authentication token from the Google Account,
- Use that token to retrieve authentication cookie from Google App Engine.
Android Manifest
Accessing accounts in the Android requires security permissions in the Android manifest.
For more information about the permissions visit documentation.
Retrieving Google account
First step during authentication is to retrieve account’s token. Accessing accounts is done via AccountManager, which can be instantianed by passing Android context to the get method. Then we retrieve accounts for our domain using getAccountsByType.
We want to retrieve account for the given username (for this example email is in format username@gmail.com).
When we have the account we are able to get security token from it.
During that process error can occur, asking user for permission to access accounts. This will be passed as the AccountManager.KEY_INTENT
paramter in the bundle.
Refreshing Auth token
By default after 24 hours our auth token expires, and requests made with expired token will result with an unathorized status code (401).
Following snippet allows you to get refreshed for the given account.
Making requests with token
This part requires an application to be hosted on AppSpot.
AppSpot is Google platform for hosting Google App Engine apps. For more information visit AppSpot website.
Let’s say that your application is simply named ‘test’, so it’s address is:
Authentication
Google App Engine provides a special path for authentication using token. The path we will use contains a redirect to localhost:
The whole URL should look like this:
As you can see we have to append our token at the end. Then we send a GET request to the mentioned URL and we are almost done.
Google App Engine token cookie
We have to use the same HttpContext, that we used for authentication, for every request in the application.
For the authentication request the HTTP status code 302 (HttpStatus.SC_MOVED_TEMPORARILY
) is OK - we just don’t want to follow any HTTP redirects, because we will move to another screen in our application.
From now on we can send authenticated requests using our HttpContext and enjoy SSO for the Google App Engine and Android apps along with other goodies that those technologies gives us.
Autor: Tomasz Wójcik
Programista, konsultant IT. W pracy zajmuje się głównie Javą, skrupulatnie zgłębia tajniki Rubyego na szynach. Kiedyś programował gry w C, Objective-C i ActionScript 3 (oraz sterowniki w asemblerze), teraz robi to wyłącznie po pracy. Wielki zwolennik gita.