I'm having some auth loop problems and pretty sure it is boost module related. I've tried having boost not cache js but it didn't help. If anyone is running boost with fb connect, please share your settings.

Comments

nardberjean’s picture

It does not work for me but I do not know if it is related to boost.

mikeytown2’s picture

Does it run hook_user on login?

adub’s picture

I'm groping in the dark but as far as I can see hook_user is called on logout and view. Don't know if Dave Cohen can shed any more light. I've switched off boost and fb module seems to be playing nicely now so it looks like there is currently an incompatibility here.

Dave Cohen’s picture

I've never used boost.

But with caching, you want to treat connected users as if they were logged into drupal. If a user is connected, there will be a handful of cookies all starting with your app's APIKEY. For example if your apikey is 1234, and the cookie 1234_session_key is found, you should not serve a cached page to that user.

If you do, the page will always seem to come from a not-connected user. But the javascript that executes on the page will determine the user is connected, and attempt to refresh the page. That's why the infinite loop.

In fb_settings.inc, the code disabled Drupal's cache. But it can't disable a cache that sits in front of drupal.

nardberjean’s picture

Boost do not cache POST request, and once a post request set a cookies, that cookie prevents boost from caching, if I understand well. So regular and openid login probably use post request.

Dave Cohen’s picture

Right but facebook connect uses javascript completely independent of the original page request.

mikeytown2’s picture

In fb_settings.inc, the code disabled Drupal's cache.

Mind posting the code and how it gets triggered in JS?

Dave Cohen’s picture

The code is sitting in modules/fb/fb_settings.inc. It just sets $conf['cache']=0.

This stuff happens in PHP not javascript. If you have a cache set up in front of Drupal, there's nothing my code can do to help. You have to poke a whole in your caching mechanism so that if facebook's cookies are set, the request goes to the server instead of from the cache.

nardberjean’s picture

Well boost is not an obscure thing rarely used. It may be almost a necessity for numerous web site, eg on shared hosting, where drupal may show very slow and other cache system may not be available or much more difficult to install than boost.

mikeytown2’s picture

Can I get a backtrace of how this function gets called?

/**
 * Forces the session_name and session_id to be appropriate when Facebook controls the session.
 * Call this function from custom session_inc files, before session_start() is called.
 */
function fb_settings_session_helper() {
  if (isset($_REQUEST['fb_sig_api_key'])) {
    // It's a canvas page or event callback.
    fb_settings(FB_SETTINGS_APIKEY, $_REQUEST['fb_sig_api_key']);
    fb_settings(FB_SETTINGS_TYPE, FB_SETTINGS_TYPE_CANVAS);
    
    if (isset($_REQUEST['fb_sig_session_key'])) {
      // User has authorized the app, facebook controls session.
      fb_settings(FB_SETTINGS_SESSION_KEY, $_REQUEST['fb_sig_session_key']);
    }
    elseif (isset($_REQUEST['_fb_fromhash'])) {
      // _fb_fromhash is a cryptically named parameter sometimes appended to URLs on canvas pages.
      // If present, it can be used as a session for users who have not even authorized the app.
      fb_settings(FB_SETTINGS_SESSION_KEY, $_REQUEST['_fb_fromhash']);
    }
  }
  elseif (variable_get('fb_session_cookieless_iframe', FALSE) &&
          function_exists('_fb_settings_parse') &&
          ($session_key = _fb_settings_parse(FB_SETTINGS_SESSION_KEY))) {
    // In special cases we embed the session key in the URL.
    // This is one way to force a session when a browser will not accept a cookie from an iframe.
    if ($label = _fb_settings_parse(FB_SETTINGS_CB)) {
      if ($apikey = db_result(db_query("SELECT apikey FROM {fb_app} WHERE label='%s'", array($label)))) {
        fb_settings(FB_SETTINGS_APIKEY, $apikey);
        fb_settings(FB_SETTINGS_LABEL, $label);
        fb_settings(FB_SETTINGS_SESSION_KEY, $session_key);
        fb_settings(FB_SETTINGS_TYPE, FB_SETTINGS_TYPE_CANVAS);
      }
    }
  }
  else {
    // Were not in a canvas page.
    // We might be in a facebook connect page.  We have to inspect cookies to make sure.

    $session_key = '';
    
    // TODO: make this more efficient.
    foreach ($_COOKIE as $key => $value) {
      if ($pos = strpos($key, '_session_key')) {
        $apikey = substr($key, 0, $pos);
        $session_key = $value;
        break;
      }
    }
    if (isset($apikey)) {
      fb_settings(FB_SETTINGS_APIKEY, $apikey);
      fb_settings(FB_SETTINGS_SESSION_KEY, $session_key);
      fb_settings(FB_SETTINGS_TYPE, FB_SETTINGS_TYPE_CONNECT);
    }
  }

  // By default Drupal will name the session based on the $cookie_domain.
  // When facebook controls the session, we need a different name.
  if (!isset($_REQUEST['fb_session_no']) && // (a way to override this)
      fb_settings(FB_SETTINGS_APIKEY) && fb_settings(FB_SETTINGS_TYPE)) {
    // Set session name differently for each app.
    //session_name('SESS' . fb_settings(FB_SETTINGS_TYPE) . md5(fb_settings(FB_SETTINGS_APIKEY))); // not sufficient!
    // In fb connect, one user may log out of facebook, and another log in using same browser.  We never get a logout event! For this case we must make session names different.
    session_name('SESS' . fb_settings(FB_SETTINGS_TYPE) . md5(fb_settings(FB_SETTINGS_APIKEY) . fb_settings(FB_SETTINGS_SESSION_KEY))); // unique to session, if known.
    
    if (fb_settings(FB_SETTINGS_TYPE) == FB_SETTINGS_TYPE_CANVAS && fb_settings(FB_SETTINGS_SESSION_KEY)) {
      // Spoof a cookie, and make it the same for both FBML and iframe canvas pages.
      $session_id = 'fb_canvas_' . md5(fb_settings(FB_SETTINGS_APIKEY) . fb_settings(FB_SETTINGS_SESSION_KEY));
      session_id($session_id);
      $_COOKIE[session_name()] = $session_id;
      fb_settings('fb_session_id_force', $session_id);
    }
  }

  // Also disable Drupal's caching, because a 'connected' user is not truly anonymous.
  if (fb_settings(FB_SETTINGS_SESSION_KEY)) {
    $GLOBALS['conf']['cache'] = 0;
  }
}

Edit: Does this function get called when your using boost and this module?

giorgio79’s picture

subs

nirad’s picture

subscribing

gausarts’s picture

Hi,

Currently I have my drupal cache set to 5 minutes normal, and the login block is still presented even when the user is already logged in via FB. Weird.

UPDATE: my mistake about the above login block problem, sorry. I followed the handbook too strictly to leave the advanced user settings alone, so I left it alone. It's all there to touch in fact :) But still wonder about the rest of my question:

I'd love a confirmation. Will this fb connect even fail with memcache and authcache, too?

junro’s picture

subscribe

Dave Cohen’s picture

@mikeytown2: to see how fb_settings_session_helper is called, see fb_session.inc, which is a replacement for drupal's session.inc. It's called early in drupal's bootstrap. It's main purpose is to change the session id when facebook controls the session.

I agree it would be nice to work with Boost and all other caching mechanisms. The key is that with any caching option which is in front of drupal, it's possible that none of drupal's code will be called. These caches need to be configured to recognize facebook's cookies as well as drupal's. (And note that in DFF 3.x, the cookies have changed to a single cookie, because facebook's new libs do it that way).

If anyone gets Boost configured correctly, please share how you did it.

jghyde’s picture

I have boost configured with fb module and it seems to be working fine. Boost doesn't cache authenticated users, it appears.

I did not do anything special.

The site is http://www.sanangelolive.com/
and http://apps.facebook.com/sanangelo

Joe

loze’s picture

I was having this problem with boost and infinite looping.

Make sure you are excluding the path fb* from being cached by boost. (I wasn't)
Delete all the boost cached files in cache/normal/[yoursite]/fb/
and it stopped.

Hope that helps someone.

13rac1’s picture

Status: Active » Fixed

Fix is #17. Closing old issue.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.