Using facebook connect (only) to authorize users with authlogic

Posted by lee on May 2nd, 2010

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.

mig_constraints is not compatible with rails 2.3

Posted by lee on October 25th, 2009

Although it’s old, mig_constraints has sat in my rails plugin directory for a while now because it adds much needed foreign key support to ActiveRecord.

I’m on of those crazy guys that thinks a relational database should maintain relational integrity, so it’s been a staple of my rails projects for some time. Unfortunately when I recently upgraded to rails 2.3.4, it created a bizarre obscure error that seems to indicate it’s not compatible with rails 2.3 at all.

As far as I can tell, the best candidate for a replacement is this github project but I’ve not yet had the time to try it. For now I simply removed the plugin from my project and db:migrate reverted to a nice working state.

Read the rest of this entry »

Setting up a kick-ass rails server on Ubuntu 9.04 (Jaunty)

Posted by lee on June 27th, 2009

I recently created a new slicehost and thought I’d try the latest Ubuntu release with it. Unlike brightbox hosting, you only get a plain boring ubuntu installation out of the box on slicehost (and various other VPS-based hosting services).

A bit of aptitude

Ubuntu/Debian make it really nice and easy to install packages, but this time it still took me a couple of hours to install everything.

For my (and your) future reference, here’s all you need to create a full rails/mysql/apache platform on Ubuntu 9.04:

apt-get install rubygems ruby1.8-dev mysql-server-5.1 libmysqlclient15-dev apache2 libopenssl-ruby libxslt1-dev libcurl4-gnutls-dev build-essential apache2-prefork-dev libapr1-dev libaprutil1-dev libmagickwand-dev git-core subversion

gem install rails --version=2.2.2
gem install rake mysql passenger

cd /to/your/app
rake gems:install

Be sure to follow the instructions that appear after installing passenger, and then that’s it! Make sure you set the version number of rails that you need, or remove the –version parameter if you just want the latest stable release.

(Note: the last line assumes you’ve added all the gems your application requires to config/environment.rb. You could make the above list of packages even more minimal, but they cover plenty of common gem dependencies).

Going the extra mile

If you need to setup an environment to create screenshots programmatically, you’ll need a virtual X server, firefox and selenium (which is Java-based). That’s also fairly easy:

apt-get install xvfb firefox latex-xft-fonts sun-java6-jdk gsfonts-x11 sun-java6-fonts
gem install selenium-client

Do you have any must install packages when creating a new server? Please add them in the comments below.

Nokogiri fails to work on Solaris (11), but fix it like this!

Posted by lee on March 31st, 2009

I’ll have a better fix up in the near future, but for now, the ruby gem “Nokogiri” crashed out on me on Joyent’s Solaris platform. Its error was a little cryptic unless you’re familiar with libc. I can’t reproduce it here because unfortunately it’s lost in the sands of scrollback buffer.

The crux of the problem was the reference to a missing vasprintf function. Nokogiri has an extension implemented in C that speeds it up with native functions. The extension is compiled when you do ‘gem install nokogiri’ and will compile even though the vasprintf function is missing in your environment.

vasprintf is available in Linux, but not in Windows or Solaris. Nokogiri already have a workaround in place for Windows, but they don’t yet detect the issue in Solaris so the error still occurs. I plan to submit a patch to detect this automatically. If for any reason you need to get nokogiri working immediately on your Solaris 11-based Joyent accelerator, I did the following after installing the nokogiri gem:

cd /opt/local/lib/ruby/gems/1.8/gems/nokogiri-1.2.3/ext/nokogiri/
vi native.c
[remove the #if XP_WIN line and its corresponding #endif]
vi native.h
[remove the #if XP_WIN line and its corresponding #endif]
make
make install

FWIW, on Linux and Mac OS X nokogiri just works.

Getting Rails 2.2 to work on Mac OS X, despite the MySQL ruby “gem”

Posted by lee on January 29th, 2009

rubygems makes package management a nightmare. This is demonstrated every time you try and setup a new server using your operating system’s ruby/rails packages. It gets fully demonstrated when you try and upgrade to Rails 2.2 on a Mac. You can go read the full details of the nightmare if you’re so inclined.

The summary is that rails 2.2 removes the mysql driver and so you have to install a native driver using rubygems. Normally this would be a single command, but MySQL is a mess on Mac OS X. If you have a working MySQL installation on a Mac, chances are you’ve used MAMP and/or installed it yourself.

After about two hours of pain, I finally came across this forum post which has the horribly hacky but wonderfully simple idea of copying the mysql driver that worked in older versions of rails into your rails 2.2 app! This finally worked! On my Mac, this meant running the following command:

 cp /Library/Ruby/Gems/1.8/gems/activerecord-2.1.2/lib/active_record/vendor/mysql.rb ~/Software/myapp/lib/

When I restarted my rails app, it actually worked! Joy!

It’s worth noting that it’s probably worth pushing through the pain to install the native mysql gem on your production servers, but this technique is a winner to keep development on the go.




© 2009 Lee Mallabone
Powered by Wordpress. Theme provided by Wordpress Themes - Absoluteshield Internet Eraser