I recently started playing with the JREngage plugin for Android. I have been a long time user of Janrain’s multi-host OpenID authentication services, and was interested to see how easily I could build a login system within my Android application. It was trivial to get this working. And, as a bonus, you can then have your Android application seamlessly talk to your webapp (provided authentication into it is also via Janrain). There was one implementation issue which stumped me for a day related to the way Rails handles authentication (specifically how and when it decodes session cookies to prevent against CSRF attacks), so I thought I would document that here.
First, if you follow the instructions here on the Janrain documentation, you can quickly get an Android application running using the JREngage libraries.
It was not immediately obvious to me that there are two steps when you use JREngage to authenticate an Android application. The first is when your Android application logs in using any of the OpenID providers supported by Janrain. Once this is completed, you will be returned to the callback jrAuthenticationDidSucceedForUser in which you can then extract information from the authInfo dictionary. For example, once control is returned to my application, I used this bit of code to extract the email address which I then display in my Android application:
Here is the code I used. First, I liked the Java REST client provided for on Lukencode’s blog. After adding this to my project, I then instantiate a REST object, and then use the session cookie to get inside my application. I banged my head against this for a while, because it did not work originally. I put a debugger statement inside my application_controller.rb to see whether it was pulling the session back from the request coming from Android, and initially it was not. I sniffed out the HTTP header traffic using wireshark to make sure the cookie was being sent in the request header and it was. I inspected the session cookie from the Rails request object and decoded it by hand, and it looked fine, but for some reason when it reached my application controller authentication method the session did not exist. I then noticed the CSRF cookie which was not being sent on the Android request. And, then I realized I needed to ignore this check. If you place the code at the top of your controller to ignore the authenticity token, your webapp will properly retrieve and use the session cookie.