Many sites use Facebook Connect today, hoping to share the popularity of Facebook, pulling Facebook users’ profile/feed, and publishing their own site-generated contents to users’ feed/wall. So most Facebook Graph tutorials, including Facebook’s own documentation, tell us how to add Facebook Connect button to our sites, how to set the redirect URL, how to grab the access token, and how to request for users’ privacy.
But I wanted to rely on Facebook instead of implementing my own user login/registration processes. I’m still doing investigation and I don’t have a working example yet so this post is just my rough thoughts. I will come back and revise it when I get the implementation experience.
Old cookie based user/password authentication
We’re all used to the old scenario that when creating a new website with user interaction, we create a user table and store users’ login name and hashed password in that table. When the user logs in, we check the submitted form against the items in database and if they match we create a cookie for the user containing the login name and a hash generated by some hashing method (This hash is for validation so that people can’t send a fake cookie claiming they’re someone. One way to generate it is to apply HMAC to the login name and hashed password in database). So when the user request something next time, we don’t need his name/password but only validate the cookie against the credentials stored in database. Hopefully this cookie has a long life (if we provide a “remember me” option) so the user won’t be required to input his name/password for a long time.
I was doing this all the time and I tend to forget what it’s about. Essentially when our sites have user generated contents, we need to identify the current user so that when he writes something we have an identifier to store into the record he creates. The next day he comes again and we are still able to identify him so he can happily find the contents he created yesterday. All what we need is just identification so that everyone can keep their secret or property on the site safe.
Facebook Connect as identification service
The concept of Facebook Connect (or any other third party login system like Google/Yahoo, or OpenID) is that instead of identifying users by username/password, we ask Facebook who they are. This seems very clear but it tool some time for my stubborn mind to realize. So it becomes clear that the most important information we want from Facebook is the user’s Facebook ID or some other identifier.
- Facebook ID is a number and it’s quite safe to use
- When asking for authorization, ask for extended permission to access the user’s email address. Email address is also a good identifier and in some sense it’s better than Facebook ID because Facebook ID is only valid in the Facebook namespace but email is globally unique (just consider adding another third party login).
Stack Overflow’s approach
Then how to remember the user across requests and sessions? Cookie, of course. We can put the identifier acquired from Facebook into the cookie, together with a hash to verify its authenticity.
Stack Overflow sets a good example for this approach. And I guess it uses email address as identifier. You can verify this by following these steps:
- Make sure you’re using the same email address for your Google and Facebook accounts.
- Log into Stack Overflow via Google and setup your profile.
- Log out and log in again via Facebook.
- Here you see you are entering the same account as logging in via Google.
And Stack Overflow stores some authentication information in a cookie named “usr”. You can copy it to another computer, open stackoverflow.com, and wow, you are already logged in! Even if you didn’t logged into Google/Facebook.
Stack Overflow lets the cookie live 6 months so if you logged out of Google/Facebook, it wouldn’t affect your login status on stackoverflow.com. At first it seemed surprising to me, but I soon realized that it’s just the same as using username/password for cookie based authentication. Stack Overflow just knows your email address and maybe some more information about you that you authorized it to access. And it assumes that no one will be using this computer (or accurately, this user agent where the cookie resides) to ask/answer questions on stackoverflow.com. That might be a bad design and they should have provided a “remember me” option. Even if someone else accessed your Stack Overflow account, he wouldn’t be able to do harm to your Facebook account, since the authorization code and access token Facebook gave stackoverflow.com expired in hours after issuance. As far as I know stackoverflow doesn’t utilize the Facebook Graph API to explore the user’s account except requesting some basic profile information. Even if the bad guy wants to publish to your Facebook feed through some stackoverflow feature, stackoverflow would still need to run the oauth process to obtain authorization code and access token but in this case, the bad guy can’t get through unless he knows your Facebook login credentials.
A large part of this post is based on observation of OAuth 2.0, especially Facebook’s implementation (they don’t have the refresh token), and Stack Overflow. As far as I know Google/Yahoo! also can grant access to user’s email address information but some OpenID providers don’t necessarily have email address. But Stack Overflow just needs to develop a namespace mechanism to ensure identifiers from different parties can be distinguished.
Relying on third party login may seem dangerous, in that if Facebook is down for some period or it dies some day, our users won’t be able to log in. But if you get the email address you can also send users an email to let them set up password in your own database.
Quora is another interesting example. Say you have registered an account with Quora using the same email address as the one used to register Facebook. Next time when you want to log into Quora, click the “Connect to Facebook” button. When you authorize Quora to access your Facebook profile, Quora discovers the email address and finds that this email address already has an account so it just needs to log you into that account and connect it to the Facebook account.
It’s different with Stack Overflow in that whatever account you use to log in, it requires you to set up a password on its own site. Twitter doesn’t provide email address so it also asks the user for an email address. So it’s not totally relying on third party authentication, but only associating some other social networks so that it can easily send updates to user’s tweets or feed and amplify the social effect to a greater extent. It doesn’t matter if twitter vanishes in 5 years.
We can also consider asking for more permissions when implementing our Facebook based user system, to utilize the power of this social monster. Why not? That’s what Facebook Connect was designed for.