tags:

views:

3707

answers:

1

I'm using the 3.0 version of the Facebook Developer Toolkit to build an MVC iframe Facebook app, and having some trouble getting the infinite session key immediately after it is granted.

When the user first hits my application settings View to set their preferences, they just have the usual expiring session key from Facebook. No problem.

Depending on the preferences they select, I prompt them for the offline_access extended permission using the Facebook javascript client library FB.Connect.showPermissionDialog method. Again no problem, they grant the permission.

At this point a new non-expiring (infinite) session key is issued. I need to save this to my database for future use. The problem is, I can't figure out how to get it immediately when I need it. The Facebook cookies containing the session info are not being updated until a few more page refreshes go by.

There is an open bug in the Facebook bug tracker at bug ID 6421 related to this, but I am looking for a server-side solution using the Facebook Developer Toolkit 3.0 release. I'd like a way to tell the FDT api to go out to Facebook and get the new session.

I know the new session is established on the Facebook side. There is a telltale GET on http://www.facebook.com/extern/login%5Fstatus.php that shows up in the Firebug Net panel immediately after the user grants the offline_access permission and has a response with some javascript containing the new non-expiring session key. And if I continue using the old expiring session key, I get invalid session errors back from Facebook.

In my controller, I have code like:

[AcceptVerbs(HttpVerbs.Post)]
[FacebookAuthorization(IsFbml = false)]
public ActionResult Index(FormCollection collection)
{
        var api = this.GetApi();
        var userid = api.Session.UserId;
        var key = api.Session.SessionKey;
}

This is getting the old SessionKey, not the new non-expiring one.

I don't have this problem if I decorate my ActionResult with ExtendedPermissions="offline_access" on the GET, forcing the user to grant the offline_access prior to even seeing the page, but I don't like that user experience. I much prefer to prompt using javascript only when needed, and the javascript permissions lightbox is much nicer than the full page width permissions prompt when I use ExtendedPermissions="offline_access".

I've also tried intercepting the call to my xd_receiver (which I've made a View so I can hit a debugger breakpoint in its controller and inspect the incoming request from Facebook). It gets hit during the granting of the extended permission, but again it has the old expiring session info referenced.

So to recap, I am looking for a way using the Facebook Developer Toolkit to force a session refresh from Facebook and get the new infinite session key (and secret).

+5  A: 

Hate to answer my own question, but it sure beats not having a solution. Hope this helps someone else.

The root cause of the problem is that cookies are not being updated with the new session in a timely fashion, or until the page re-loads. Facebook dev says this is a browser issue. All Facebook client libraries including the .NET Facebook Developer Toolkit rely on the cookies for session info. So it is a browser bug, or a Facebook bug, or a Facebook design flaw to put so much dependence on the cookies. See Facebook bug 6421.

Fortunately Facebook has a new Javascript client library in alpha which has a cookie-less option that works.

<div id="fb-root"></div>
<script type="text/javascript"
    src="http://static.ak.fbcdn.net/connect/en_US/core.js"&gt;
</script>

<script type="text/javascript" >

    // initialize the library with the API key, set cookie: false
    FB.init({
        apiKey: your_facebook_apikey,
        cookie: false,
    });

    FB.getLoginStatus(function(response) {
        if (response.session) {
            alert(response.session.session_key);
        } else {
            // re-prompt for permissions or do some other exception handling
        }
    }, true); // critical optional parameter to force a refresh

</script>

(omitting facebook permissions prompts and other stuff for brevity)

In my MVC app I am prompting for permissions in Javascript. Prior to submitting my form, I do the getLoginStatus call and put the sessionkey and secret into form fields so they get posted to the controller.

The new Javascript client library is on github at http://github.com/facebook/connect-js

Pat James