views:

31

answers:

1

I am integrating facebook connect with my application which uses authlogic, facebooker, and the authlogic_facebook_connect plugin. After I log in with facebook, I get redirected to the front page of the site (as per my code) - but the page never loads! - it hangs. Looking at the development log, I see that something is continuously trying to load a user from the database.

It just keeps going on and on and every time I reload development.log (while the page is still trying to load) it just gets bigger - development log on bottom.

Here's the info I got:

  1. Doing some debugging, I traced the issue to the function meant to persist a user session with authlogic (no params):

    UserSession.find

  2. Looks like Authlogic is trying to find a user in the database with a certain persistence_token. Looking directly at that record through the console - its persistence token is null (that could be just because the next thing a properly functioning authlogic would do is to set that persistence_token - not sure though).

Can anybody give me any pointers?

Thanks!


[4;36;1mUser Load (0.7ms)[0m   [0;1mSELECT * FROM "users" WHERE ("users"."id" = '4') LIMIT 1[0m
[4;35;1mUser Load (0.6ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."facebook_uid" = 100001121293021) LIMIT 1[0m
[4;36;1mUser Load (0.2ms)[0m   [0;1mSELECT "users".id FROM "users" WHERE ("users"."persistence_token" = 'ddd6b0d160321e55266db847d0b4558e9ed76ab220ef3fce655c24c5d24286d56d728deda76b44741121b0b78e1c266537fbfe00bf01206a393090c5c1f475' AND "users".id <> 4) LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = '4') LIMIT 1[0m
[4;36;1mCACHE (0.0ms)[0m   [0;1mSELECT * FROM "users" WHERE ("users"."facebook_uid" = 100001121293021) LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT "users".id FROM "users" WHERE ("users"."persistence_token" = 'ddd6b0d160321e55266db847d0b4558e9ed76ab220ef3fce655c24c5d24286d56d728deda76b44741121b0b78e1c266537fbfe00bf01206a393090c5c1f475' AND "users".id <> 4) LIMIT 1[0m
[4;36;1mCACHE (0.0ms)[0m   [0;1mSELECT * FROM "users" WHERE ("users"."id" = '4') LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."facebook_uid" = 100001121293021) LIMIT 1[0m
[4;36;1mCACHE (0.0ms)[0m   [0;1mSELECT "users".id FROM "users" WHERE ("users"."persistence_token" = 'ddd6b0d160321e55266db847d0b4558e9ed76ab220ef3fce655c24c5d24286d56d728deda76b44741121b0b78e1c266537fbfe00bf01206a393090c5c1f475' AND "users".id <> 4) LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = '4') LIMIT 1[0m
[4;36;1mCACHE (0.0ms)[0m   [0;1mSELECT * FROM "users" WHERE ("users"."facebook_uid" = 100001121293021) LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT "users".id FROM "users" WHERE ("users"."persistence_token" = 'ddd6b0d160321e55266db847d0b4558e9ed76ab220ef3fce655c24c5d24286d56d728deda76b44741121b0b78e1c266537fbfe00bf01206a393090c5c1f475' AND "users".id <> 4) LIMIT 1[0m
[4;36;1mCACHE (0.0ms)[0m   [0;1mSELECT * FROM "users" WHERE ("users"."id" = '4') LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."facebook_uid" = 100001121293021) LIMIT 1[0m
[4;36;1mCACHE (0.0ms)[0m   [0;1mSELECT "users".id FROM "users" WHERE ("users"."persistence_token" = 'ddd6b0d160321e55266db847d0b4558e9ed76ab220ef3fce655c24c5d24286d56d728deda76b44741121b0b78e1c266537fbfe00bf01206a393090c5c1f475' AND "users".id <> 4) LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT * FROM "users" WHERE ("users"."id" = '4') LIMIT 1[0m
[4;36;1mCACHE (0.0ms)[0m   [0;1mSELECT * FROM "users" WHERE ("users"."facebook_uid" = 100001121293021) LIMIT 1[0m
[4;35;1mCACHE (0.0ms)[0m   [0mSELECT "users".id FROM "users" WHERE ("users"."persistence_token" = 'ddd6b0d160321e55266db847d0b4558e9ed76ab220ef3fce655c24c5d24286d56d728deda76b44741121b0b78e1c266537fbfe00bf01206a393090c5c1f475' AND "users".id <> 4) LIMIT 1[0m
A: 

Got it! In normal user registration with authlogic, here's what happens: before_validation :reset_persistence_token, :if => :reset_persistence_token? What this does, is set an initial persistence_token if it is blank

For some reason, the authlogic_facebook_connect plugin skips this validation, causing a NULL persistence_token field to be sent to the database.

In my users table, I had the field persistence_token as such

t.string :persistence_token

it should be defined like that, but making sure that it's not null:

t.string :persistence_token, :null => false

Now, instead of hanging the browser, you get a sqlite error saying that persistence token is null. That's better, now we know what's going on.

Going to the validate_by_facebook_connect method of the authlogic_facebook_connect plugin located inside vendor/plugins/authlogic_facebook_connect/lib/authlogic_facebook_connect/session.rb, where it says

new_user.send(:"#{facebook_uid_field}=", facebook_session.user.uid)
new_user.send(:"#{facebook_session_key_field}=", facebook_session.session_key)

add another line, so it reads:

new_user.send(:"#{facebook_uid_field}=", facebook_session.user.uid)
new_user.send(:"#{facebook_session_key_field}=", facebook_session.session_key)
new_user.reset_persistence_token

now we make sure we have a persistence token set when we first create the user. do it again, browser doesn't hang, user gets created, welcome to a working authlogic facebook connect setup.

Even though I included the fix in the authlogic_facebook_connect plugin, this is really an authlogic issue.


EDIT:

  1. I submitted a ticket to the authlogic github page about this issue
  2. I wrote a blog post about this issue to help others that get stuck with it.
yuval