Search code examples
objective-cfacebookoauthios4xauth

Facebook login programmatically using OAuth/XAuth(?)


I am making an app that needs to be able to share stories to Facebook, using a password and email-address that was set somewhere programmatically (not using Facebook-Connect, mostly because I want my own design, whether you log in to Twitter or Facebook from the app).

I have done this with Twitter and XAuth already, and that works brilliant. Is there any way I can achieve the same with Facebook, or just regular OAuth? (Or does Facebook support XAuth, that would make it a lot easier?)
Is there any other way I can achieve what I want?


Solution

  • The theory is that your app should never see the user's password.

    In practice, since the code all runs in your app, it's trivial to get the user's password (and it's about as trivial to present a similar UI to grab the user's password).

    Since you have full source code, it should be easy enough to just call the function that does logging-in with the username and password. I don't recommend this:

    • Facebook probably won't like it, and might revoke your app's API key.
    • You shouldn't be storing usernames/passwords unless you absolutely have to, especially in NSUserDefaults (which Settings.app uses) since it's completely unencrypted.
    • Setting.app doesn't support password fields.
    • The user should not have to exit your app, go to Settings, add login details, and switch back to your app. It's a bit better with "multitasking", but not that much better.

    What's wrong with using the normal Facebook login screen?

    EDIT: More details...

    • AFAIK, you cannot reliably encrypt NSUserDefaults as saved by Settings.app. You do not get to decide which file this is written to (Library/Preferences/com.example.myapp.plist, I think). In iOS 4, you can set NSFileProtectionKey=NSFileProtectionComplete, but that has a bunch of problems:
      • You set this inside your app. The user can go to Settings.app before running your app.
      • While it's supposedly possible to include Library/Preferences/com.example.myapp.plist in your app zip/ipa, I don't think it's possible to include the NSFileProtectionKey attribute.
      • NSUserDefaults updates the plist "atomically" by writing the new plist to a new file and renaming the file over the old one. The new file is unlikely to have NSFileProtectionKey=NSFileProtectionComplete.
      • Ultimately, if you give control of the data over to an API that makes no guarantees about security, it's insecure (NSUserDefaults seems prone to leaving lots of temporary files lying around...). Apple's provided the keychain specifically to store passwords (there's even some decent example code!); use it.
    • Apple does not recommend using Settings.bundle and also your own settings screen — you're supposed to pick one or the other.