Using facebook connect (only) to authorize users with authlogic

I’ve been working on our semi-stealthy new webapp for the last couple of months and I’ve been putting off fixing a bug for ages because it was so damned weird.

We want users to be able to sign-up with facebook connect, and not have to mess about creating a new account and setting Yet Another Password. So I grabbed authlogic and got the facebook connect plugin for it and got to work.

Everything was fine and dandy using facebook connect to authorize a bunch of existing users I had in my database, but as soon as it came to signing up new users, ruby would suddenly hit an infinite loop that would bring rails and my laptop to its knees.

I could see from the logs that it was some kind of validation failure:

SELECT * FROM `users` WHERE (`users`.`id` = '498') LIMIT 1
CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`facebook_uid` = 1469530132) LIMIT 1
CACHE (0.0ms) SELECT `users`.id FROM `users` WHERE (`users`.`persistence_token` = BINARY '42baaa5f7ae2a550147ac0d88ffa72928ebc75d5ce23d5d65b3c87e972e9d848cf7ad5afb1bf532e2c2780a52f8a9c2bbeee43fce89d8cbbab69eddee10a0d4b' AND `users`.id <> 498) LIMIT 1
CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`id` = '498') LIMIT 1
CACHE (0.0ms) SELECT * FROM `users` WHERE (`users`.`facebook_uid` = 1469530132) LIMIT 1
CACHE (0.0ms) SELECT `users`.id FROM `users` WHERE (`users`.`persistence_token` = BINARY '42baaa5f7ae2a550147ac0d88ffa72928ebc75d5ce23d5d65b3c87e972e9d848cf7ad5afb1bf532e2c2780a52f8a9c2bbeee43fce89d8cbbab69eddee10a0d4b' AND `users`.id <> 498) LIMIT 1
... etc ...

After lots of research and hair-pulling I managed to find a jewel of hint; ticket 68 in authlogic’s bug tracker. In your User model, add a before_connect method, (a hook provided by the authlogic/facebook plugin). It needs to tell authlogic that you need a new persistence token.

    def before_connect(facebook_session)
        logger.info("HEY FACEBOOK, HOW'S IT GOING? SO LOVELY TO SEE: #{facebook_session.user.name}")

        # Authlogic isn't as magic as we thought: tell it we need a persistence token, based on advice
        # in http://github.com/binarylogic/authlogic/issuesearch?state=closed&q=persistence#issue/68
        self.persistence_token = reset_persistence_token
    end

With the above in place, new users can register as quickly and easily as clicking facebook’s “Connect” button. Without the above, authlogic is left infinitely searching for a persistence token that hasn’t been, well, persisted.

Note: there’s nothing that says you must have a persistence token when using authlogic, and an alternative workaround is probably to configure your authlogic subsystem to use a different token scheme. However, the persistence token is a common web-based session model and we didn’t want to dump it.

Advertisements
This entry was posted in Rails. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s