Hacker News new | past | comments | ask | show | jobs | submit login
Facebook breaks logins (facebook.com)
117 points by apoorvamehta on Feb 6, 2013 | hide | past | favorite | 52 comments



This is a good time to remind ourselves: Facebook's API is a service and can be a single point of failure for your business. Unlike AWS, you don't even pay for it and it has a history of being problematic[1].

Allowing users to log in to your application using Facebook is quite common. It can be easier for users. It can give you access to demographic data with less work. But the API can die, change, or act generally unpredictable. And you have zero control over it.

This particular issue is impacting 9gag, Pinterest and others. Whilst many of these sites support user logins without Facebook, just as many of them don't. Imagine if tomorrow Facebook charge to connect to their API or there's some extreme exploit. How much damage would your application face?

[1]: http://techcrunch.com/2011/08/11/facebook-wins-worst-api-in-...


I find it ridiculous that so many sites use FB as main login method, this is a critical part and relying on something that you have no control over, which is also probably collecting data about users that use your site, is a big red flag. Sure, it's more conveniant for many users to just click 'Login with FB', but I find it short-sighted.


I've found sites that only allow logins via Facebook to be very convenient to use. The moment I see them doing that, I know immediately that it's a site that I have no reason to use. I can move on right away, rather than wasting time with it.


You can get the best of both worlds by making it so that your user (has to?) also set a password when they finish logging in via facebook the first time.

This way, if facebook ever down (or removes their services), you have an _out_ for your users to login via the traditional username/password.


You don't even have to make them set a password when they first register - just verify their email address and handle setting a password though the usual forgotten-password flow if you ever need to.


Remember when they changed everyones default email to be username@facebook.com? Yeah, thats pretty much all you're going to get from the API.


A) not true, the API releases "primary email" which is usually NOT facebook. and B) even if it were that's why you check and verify: if u pull a @fb address don't save it, just prompt the user.

To me as both an app user and developer, single sign on feels like the Right Thing To Do. I'm sick of running through the same sign up flow for every single service I use, like a hamster wheel. Maybe the solution isn't fb, it's some kind of apple or google SSO? Why aren't AAPL and GOOG pushing their own SSO hard on the mobile ecosystems they control?


shrug maybe all my developer friends are wrong. I don't bother with FB API.

The solution is definitely not Facebook, Google, or Apple. They all plugged SSO into an existing platform and allow developers to perform actions on my behalf with the same credentials. Sadly, Microsoft's Passport.net was the closest anyone has gotten to a real solution because they treated their own properties as just another consumer. They killed that by trying to tie it directly into your Windows login which are inherently insecure.


> Why aren't AAPL and GOOG pushing their own SSO

because neither of them has a controlling amount of the required market (which is basically the entire internet!).

Mozilla has a project called persona (http://www.mozilla.org/en-US/persona/), which aims to solve this by splitting the login from verification and authentication, but preserves privacy (unlike oauth). If vendors of services can give up their desire to control the userbase, this could be the solution.


Why even verify their email address? It's already been done by Facebook?


Verify they still have access to that email.

A lot of people have 6yo+ facebook accounts. I quite enjoy the fact that my verified facebook email goes to a dead account that I only monitor on a 6 month basis... it saves me from a ton of spam.


It also gets you the worst of both worlds, in that you have to build both a Facebook auth solution, and store some form of user password hash on your servers


And the worst of all worlds for the user. When I use Facebook logins for a site, it's because I don't know if there's value in the site so I want signup and evaluation to be as quick and painless as possible. I don't want to have to go through other steps, I want a one-click registration and login.

A pet peeve of mine is when I click on the login with facebook button and the site still makes me fill out my name, username, email address, and set a password. So what's the point of logging in with facebook?


I'm assuming that you have multiple (throw-away)-facebook accounts? Because you don't give a site that you don't know has any value access to your facebook account? Right?


I have one throw away with no friends and no info (I consider this best-practice) for these situations.


It's so a) they get all you and your friends' social data, b) they can prefill your signup form and 3) to make sharing easier and friction-free.


>You can get the best of both worlds by making it so that your user (has to?) also set a password when they finish logging in via facebook the first time.

Then why are they bothering to sign in with facebook at all? It is now a more involved process than simply signing up with email/password, which is what facebook logins are supposed to be for avoiding.


Also, unlike AWS, you can't choose to migrate to a different provider in a way that will be completely transparent to your users.


I think all the points you make are obvious. If you rely on something that you have no control over, you're liable to get burned if you don't pay attention to API changes or if Facebook doesn't keep it's contracts from an architectural standpoint.

But it's also the price you pay if you want to tap into their user base. So it is what it is. You just have to keep your head on a swivel. shrugs


>But it's also the price you pay if you want to tap into their user base. So it is what it is.

It is? The facebook userbase is entirely and completely unwilling to sign up with a password? Putting a facebook login button on your site doesn't tap into facebook's userbase. If you want to try to tap into their userbase, you need actual integration with facebook, which can be done even though you had them sign up using a password. That way they can still use your site when facebook fucks up, and only the "automatically spam my friends" stuff stops working.


Interesting correlation between popularity and quality - i.e. the worst APIs are probably the most used.


Or maybe the less used APIs just don't reveal themselves as crap yet, because of the lack of experience with them?

I'm yet to see a very well done API.


That was my interpretation. In most of IT (operating systems, software, APIs, etc) the more you use something the more you grow to hate it.


Apparently, the Stackexchange network handles this by linking an account to an email id. If you cannot login by using facebook, you can use google to login provided you have the same email id and link the accounts.


For omniauth/rails people out there, we found this to work.

   fb_options[:client_options] = {
        :site => 'https://graph.facebook.com',
        :authorize_url => 'https://www.facebook.com/dialog/oauth',
        :token_url => '/oauth/access_token'
      }
   provider :facebook, api_key, secret_key, fb_options


The explanation:

> (according to) Andrew Fowler (from the comment thread on facebook)

The solution is to replace your OAuth Dialog URL: "https://graph.facebook.com/oauth/authorize?...... with the up-to-date URL: "https://www.facebook.com/dialog/oauth?....... They removed support for some parameters without fixing the redirect from their old endpoint.


This looks to have resolved it for us as well. Thank you.


I wonder if Facebook stores it's password in clear-text, since you can login with either 'Password' or 'password', does it hash the first character and the rest into 2 different hashes? If not, we have a our passwords in readable form in their database that have huge privacy and security issues.


They hash it once and save it to the database. When logging in, they generate three hashes (if I remember correctly) and compare it to the hash in the database. If any match, it logs you in.

Edit: Here's a post on the matter http://www.zdnet.com/blog/facebook/facebook-passwords-are-no...


Facebook stores three hashes of your password (let's say it's "pAssword"):

* "pAssword" - the password as it is

* "PaSSWORD" - the password, case inverted, in case you have caps lock on

* "PAssword" - the password with its first letter capitalized, for those with mobile devices that insist on Capitalizing Everything.


I don't think they store three hashes, but just try to validate password with three hashes.

Something inline this: https://github.com/bungle/web.php/blob/master/password.php#L...


What's the password doing on their server?

Also, why is there no salt in the comparison. It calls a naked crypt, that whole ... interesting ... hash() function is sitting there unused.

I have serious doubts whether this code actually serves the user's interest - despite trying to be cute and helpful


You seemingly don't understand a bit about it. And you seemingly doesn't understand how crypt works. Let me educate you:

1. When user registers, his password is hashed with that hash-function, and that hash is stored in a database (it uses random salt).

2. When user tries to access the site, a password is hashed against the hash stored in a database, and it should return same hash if matched (this is how crypt works!).

3. In non strict mode we try also two different passwords to match the hashes (just like Facebook does).

Code example:

1. $hash = \password\hash('user entered password'); // store it to db

2. retrieve hash from db, and check it:

$valid = \password\check('user entered password', $hash, false);

3. // Now these passwords are valid:

'user entered password' // == correct form

'User entered password' // == Mobile browser capitalizing first char

'USER ENTERED PASSWORD' // == CAPS LOCK on

And one line example:

$valid = \password\check('user entered password', \password\hash('user entered password'), false); // == true


Isn't that supposed to increase the chances of guessing the password? Unless there's a constraint on the number of attempts to guess the password, which I think there is.


By a factor of three, which is nothing.


Or they just make everything lower- or uppercase before checking it against the encrypted version.


Almost certainly not, since this would reduce the entropy of their passwords, making brute forcing easier.


It's more likely that they coerce to lowercase the the first letter of the password you put in and then store/compare the hash of that resulting plaintext. They could even transparently upgrade passwords created before they started doing this by using the plaintext from the next time you login successfully to regenerate the hash.


Lowercasing the first character--by itself alone--does not address inverted case scenario (e.g. "PaSsWoRd" and "pAsSwOrD" evaluate to "paSsWoRd" and "pAsSwOrD" respectively).

One way to resolve that issue is to create two versions of the password (one with normal casing and one with inverted casing, but both with the first character lowercased), sort them, and pick the first result.

    ["pAsSwOrD", "PaSsWoRd", "PAsSwOrD"].map(function canonicalize(pwd) {
        function invert(str) {
            return (str == str.toUpperCase()
                    ? str.toLowerCase()
                    : str.toUpperCase());
        }
        var head = pwd.substring(0, 1).toLowerCase();
        var tail = pwd.substring(1);
        var vers = [head + tail,
                    head + tail.split("").map(invert).join("")];
        return vers.sort()[0];
    });
Which gives the following result:

    ["pAsSwOrD", "pAsSwOrD", "pAsSwOrD"]
The three different variations get canonicalized into one version. With it, you can just store one hash instead of three.


I was having lunch recently with a few developers, and the topic of "What is the worst API you ever had to work with" came up. The unanimous answer was immediately "Facebook". Everything from the documentation, to multiple ways to do similar things (each of them incompletely documented), to deprecations that never actually go away, to arbitrary breaking changes.


I'd go with Instagram's over Facebook's.


What did you try to do?

I've worked with both and Instagram is… pretty straightforward. Granted, I only ever authenticated and consumed feeds, but still.

Facebook on the other hand is a maze of twisty little passages, all alike


Pain points we've run into:

* OAuth redirect_uri is locked to a single domain. No test.example.com/staging.example.com for testing - you need to create a new app for a testing/staging environment.

* Max of five apps in an account (see above) - we're having to register an Instagram account per app so we can create dev/test versions of the app.

* Can't grant access to other devs for an account.

* Access to the commenting API is whitelist based. API gives an e-mail address, which never responds. Trying to use the API returns JSON with a bitly link to a Google form, which also never responds. We've been waiting some time for them to respond with a yay/nay on comment whitelisting.

* Docs say you should respect privacy setting of photos, but API doesn't tell you which photos are private anywhere.

* The Google Group seems to be a place feedback/bug reports go to die.


I have to admit that I sort of struggled to understand what Facebook were trying to communicate to me when that message popped up on my account.

Maybe if you worked with the Facebook login system / followed their API frequently it would have made sense. For someone who once integrated Facebook logins into their site it felt a little bit cryptic.


I've done way too much work integrating Facebook login and payments, and their error messages never make sense. You just have to learn how to map their undecipherable gibberish into actual errors, and then go fix it.


Yep, that worked for me: added this in devise.rb: config.omniauth :facebook, FB_APP_ID, FB_APP_SECRET, {:scope => '.....', :client_options => {:ssl => {.....}, :display => 'popup', :setup => true, :site => 'https://graph.facebook.com, :authorize_url => 'https://www.facebook.com/dialog/oauth, :token_url => '/oauth/access_token'}}


Does anyone know if there is a workaround if you are currently using the FB.login method to authenticate users?


It's still broken for mobile web


http://developers.facebook.com/bugs/ is broken as well if you are logged in. Big bug.


seems fixed.


Is the United Breaks Guitars guy available?





Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: