Monday, January 25, 2010

Test cases for basic Facebook Connect integration

I recently spent a couple of days adding some basic Facebook Connect functionality to an existing site with it's own Login/Auth system. The process isn't too hard and there are several examples and even a nice tutorial which shows you exactly how to hook this up.

The tutorials and the Facebook developer wiki to a good job of getting you on the right path and putting up a quick working implementation. However, there are several subtleties that need to be addressed, depending on the requirements of the existing site. I didn't really find a good compilation of these 'test cases' anywhere. Facebook's own documentation probably references several of these but they're scattered all over their wiki page and are very easy to miss if your primary focus is getting this stuff up and running quickly.

This blog post is my attempt to compile of list of things you need to think about when adding Facebook Connect support for sign up/login or linked accounts on an existing site with its own authorization system. Here are a few characteristics (pretty standard) of the existing site:
  • Authentication using a username/email address and password
  • Cookies to help keep users logged in
  • Accounts keyed by email address (i.e. 1:1 mapping between accounts and email address)
  • Ability to reset accounts by having a temp password send to user's email address
  • Fully ajax navigation (which complicates matter a little bit)
  • Logout functionality which clears up cookies
The goals for the Facebook Connect integration are pretty simple:
  • New User Sign Up without needing to create a site-specific password (email address needed)
  • Ability for existing users to link with their Facebook account
  • 1:1 mapping between accounts on your site and Facebook accounts
  • Single sign-on experience
Let's call the existing site YouFace. I won't go into how to get stuff hooked up or explaining how to implement this - it's not too complicated and there's a bunch of information online for it. Instead, treat this as a list of a few things you probably want to test when you're done. There shouldn't really be anything ground breaking here - this was just a convenient way for me to build a list of things to test on my own site. Some of these are handled by the Facebook Connect client library, while some need your application to do the right thing. Please comment if I've missed any cases or if some just appear wrong - I would love to fix my site!
  • Sign Up should fail if the user denies permission to the app (category: sign up)

  • Since we need access to an email address, Sign Up should fail if the user provides publish permission but denies email permission (category: sign up)

  • If the user provides an email address that already exists in your system, fail Sign Up. Make sure no YouFace backend tables are modified (category: sign up, 1:1 mapping) PS - when this happens, I didn't find a way for you to de-authorize YouFace on the Facebook user's behalf. The user must manually do this if they wish you use the same account but provide a different email address.

  • Accounts created using Facebook Connect should not be able to login using YouFace's default email/password login system (category: sign in, account security). PS: Since YouFace accounts require a password and those created using Facebook Connect don't, make sure to insert a random password hash into your table to avoid silly errors

  • Accounts created using YouFace should be able to sign in without requiring to be signed into Facebook, even if when a link to a Facebook accounts exists (category: sign in)

  • Attempting to Sign Up with a Facebook account that's already linked and authorized should result in the Sign In experience (category: sign up, sign in)

  • Attempting to Sign In with a Facebook account that YouFace hasn't seen before should lead to the Sign Up experience, i.e. create a new account (category: sign up, sign in)

  • Linking a Facebook account with an existing YouFace account should add the email address from Facebook to the list of 'used addresses' in the YouFace system (category: linking, 1:1 mapping)

  • When a Facebook linked account de-authorizes YouFace, your system should record this action and change state as needed (category: authorization)

  • Linking a YouFace account with a Facebook account that's already been linked to some other account in your system should be denied (category: linking, 1:1 mapping, authorization)

  • Users with linked accounts can continue to sign in using their YouFace credentials even after they de-authorize YouFace from their Facebook account (category: linking, authorization)

  • Linking a Facebook account different from one you originally linked to an existing YouFace account should be denied. This can happen when an existing user links a YouFace account to Foo@FB, de-authorizes the app and then tries to link Bar@FB to that account (category: linking, 1:1 mapping, authorization)

  • A user who Signed Up using Facebook Connect should not be allowed to link their account to another Facebook account (category: sign up, 1:1 mapping)

  • Attempting to Sign In or Sign Up with a Facebook account that YouFace has seen, but one that has currently not authorized the YouFace app (maybe the user revoked authorization) should ask to re-authorize before proceeding. It must log the user into the original YouFace account linked with that Facebook account, i.e. no new account should be created. If that account was originally created using Facebook Connect, the primary email address should be updated to reflect the user's current Facebook contact email address else the primary email address should not be changed from what the user provided YouFace when they signed up (category: sign in, 1:1 mapping, reauthorization)

  • If a user with a linked account is logged into Facebook, they should be signed into YouFace directly (category: single sign in)

  • Users who signed into YouFace with Facebook Connect should be logged out of Facebook if they log out of YouFace (category: single sign out)

  • Users who signed into YouFace with Facebook Connect should be logged out of YouFace if they log out of Facebook (category: single sign out)

  • Users with linked accounts who signed into YouFace directly (not using Facebook Connect) should continue to remain signed in, regardless of whether they're were originally signed into Facebook, when they sign out of Facebook (category: sign in, sign out)

  • Users who created their account using Facebook Connect should not be allowed to reset passwords or have temporary passwords sent to their email addresses (category: account security)

  • This is a kinda convoluted. Users Foo and Bar both have YouFace accounts linked to Facebook. Bar is logged into YouFace with his YouFace account, and Foo is logged into Facebook, in the same instance of the browser (Bar logged in first). When Bar logs out of YouFace, Foo should not get logged out of Facebook (category: single sign out, multiple accounts ). PS: YouFace's Connect library is going to pick up a valid Facebook ID but it's that of Foo, not Bar. So you need to do more than just client-side detection of whether someone's logged into Facebook.

19 comments:

Marco Paul said...

Hello

Is there anyway I can please pick your brain on your implementation? I am trying to do the exact same thing and I am running into a few roadblocks.
Thanks!

Viraj Mody said...

Hmm, sure. Just leave a comment here and I'll see if I can help. I'm guessing the FB developer forums (http://forum.developers.facebook.com/) might be a better option though.

Marco Paul said...

i tried using the forums, but not much luck. can you explain where and how you handle your cookie authentication? are you storing user data in there to describe how they connected with the username either being a facebook id or email (standard login)?

Thanks!

Viraj Mody said...

No, the cookie (that I set) doesn't have any information about how the user connect. This information is held on the server with the session state. However, my site's cookie is NOT set when the user only signs in with Facebook so I guess I could use this to detect standard login as well. Of course, if the user is signed into FB, that cookie will be set regardless of whether my site's cookie is set or not.

Does that help?

Marco Paul said...

ok, so let me just confirm a few things. if the user logs into your site
using standard login (not fb), you use standard forms cookie authentication.
if the user logs in via fb connect, you do not create your own cookie,
you just re-use/read the cookie fb has already set. Then, you read from session
to check if the user connected via fb and if so, show your fb content.
so what if the users session expires, do you have a recover plan?

Viraj Mody said...

Sessions expire regardless of how the user signs in, so you're going to need to deal with session re-creation regardless, no? Maybe I didn't understand your question...

Marco Paul said...

no, thats fine, just checking (i always try to avoid session state when i can. also my app is mvc).

so am i on the right track from my last post on how you handle the process?

Marco Paul said...

Hi

Quick question about your data model. do you just have one table that you store all your uses (regular, linked)? also, so when a user links their facebook account to an existing account (YouFace), do u create a new account for facebook or just store the facebookid with the user record.

Viraj Mody said...

Yea, just having one table is probably easiest. When an existing user links their account to Facebook you can just add that data to a column in the existing table - there is definitely no need to create a new account.

Marco Paul said...

yeah, that's what i was thinking, but then i read one of your business rules stating when a facebook account is linked, the users facebook email address will be marked as "in use" and cannot be used again. so i was wondering where u store this.

Marco Paul said...

sorry, one last question. how are you retrieving the users e-mail address? i just noticed the api's i was going to use do not support this yet.

thanks!

Viraj Mody said...

For email: http://forum.developers.facebook.com/viewtopic.php?pid=206209

Marco Paul said...

Hi Viraj

I just moved my code from windows xp (IE 7) to Windows 7 (IE 8) and now i've noticed when a user logs in the page just goes into a refresh loop? Did you run into this or anything similar in your development? This is becoming a real pain...

Thanks!

Scott said...

Great post. I have a site that purposely allows user accounts to share the same email address. (i.e., A parent can create an account for a child and use their own email address if their child doesn't have one.)

Any hints for how to deal with that? Thanks!

Scott said...

Another question: I think you imply that if a user signs into YouFace for the first time using Facebook Connect, they shouldn't be able to add YouFace login credentials later. What about users who (gasp!) want to get off Facebook, for example?

Viraj Mody said...

Scott, that's a common scenario (some work places block facebook.com, for instance) so I did change that creed. I allow users to assign YouFace creds to accounts created using FB.

Scott said...

Thanks, Viraj. So what's considered the best practice for obtaining YouFace credentials for a FB Connect-only user?

I'm thinking there should be a button on the site's "Profile" page for the existing FB Connect-only users which goes to another page to ask for a valid YouFace ID and password. (Similar to the New User page but it only validates and saves the user's YouFace ID and (encrypted) password on the server.)

Sound good?

Anislay said...

Great post Viraj

Anislay said...

Great post Viraj