Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The "right" way to do oAuth from a mobile client

I am building a cross platform mobile application (using the Xamarian tools, MonoTouch / MonoDroid). I am trying to work through the authentication workflow and am running into a stumbling block. I have searched all over for a clear answer and have yet to find it.

Here is an overview of my current setup.

I have a web site built in nodejs. I use passport.js to do oAuth login on the web site. This works great, users can login to my site using Twitter or Facebook.

Now I want to extend this same login functionality to my mobile clients.

I see 2 options

  1. Embed the app id and app secret's in the mobile clients and make direct oAuth calls to FB or Twitter from the mobile app

  2. Proxy the oAuth calls through my existing nodejs web server (keeping the secret keys on the server)

Option 2 appears to be the preferred way (as it avoids having to "ship" the secret in the mobile apps).

I have the proxy approach mostly working.

  1. I open a WebView in my mobile client and point it at http://mysever/auth/twitter
  2. This runs through my existing passport.js code and redirects the mobile WebView over to the Twitter login page.
  3. The user then enters their creds on the twitter webpage on the device.
  4. Twitter then calls my oAuth callback URL (which is my nodejs web server).
  5. My server and Twitter handle the back a fourth handshake of obtaining the user profile information (As I understand it, this is the key to this approach, my server and twitter handle the handshake, the mobile client doesn't have to do anything or pass any tokens during this process)

Here is my problem:

  1. It is this last step that stumps me. Once the handshake is complete on my server I have the user information I need on the server and need to send it back to the mobile client application

    I can't figure out any way in the WebView control to grab the response object and grab a cookie, or header value (for instance) (this seems true for Android and iOS). I don't think it is platform specific. I think I am trying to do something that a WebView widget in mobile platforms just don't suport. It makes me think I am missing something obvious.

The only thing I have figured out is to have my web server "redirect" the mobile client browser to a fake URL that has the user info in the querystring. Something like myapp://info?userid=1234

Then in the mobile app I can hijack the URL loading and grab this url and get the data I need. I can then stash this userinfo, close the WebView control and move on to a native screen in my mobile application and user the userinfo in any subsequent REST calls to my nodejs server as a means of identifying the user.

This is massively kludgy for multiple reasons. The biggest of which is that the url is sent over the wire unencrypted and has all the data in plain text.

There has to be a better way to get the data from the web server back to the mobile client?

Or am I doing it all wrong?

like image 732
Brad Cunningham Avatar asked Feb 14 '13 23:02

Brad Cunningham


1 Answers

The most straightforward way to implement oauth for Xamarin, both for iOS and Android, is using Xamarin.Auth. The starter documentation for the client is here. I think it should maintain everything securely and you will not have to worry about having to use your node server as a proxy.

You will need to provide your Application ID as part of the calls, but I don't there are too many or any security issues to worry about there.

I know this is going against what you already have implemented, but maybe this could help simplify things a bit.

like image 79
Mike Stonis Avatar answered Dec 03 '22 07:12

Mike Stonis