If you're wondering what the "Race Condition" is, its a flaw in a system whereas it's highly dependent on timing. See the wiki here for more info.
So, the condition i have is relating to Facebook Connect and implementing a Single-Sign-On service with an ASP.NET 4.0 Web Application (Forms Based Authentication - IIS7).
The process itself (including Logout) is working nicely, but.....
Here's scenario where it's not exactly working 100%:
- User logs into Facebook.
- User navigates to my website.
- User is not logged in automatically (should be though).
- User refreshes the page, and is logged in automatically.
When i breakpoint the code in step 3 - the Facebook Cookies are not yet there (in the HttpContext.Current.Request.Cookies
).
But when the page is reloaded (step 4) - the Facebook Cookies are there.
To me, it could be a number of things:
I'm not sure if its just a case of Facebook has not yet granted access to my application to access the cookies (delay in cross-domain handshake - xd_receiver.htm), or an issue with cross-domain cookies itself and the ASP.NET Page lifecycle.
Anyone else dealt with this problem?
It's not the "be-all-and-end-all", but it's annoying (and not great from a user perspective).
EDIT:
Ok ive noticed something strange now. If i log into Facebook (via Facebook), and wait say 20 seconds, then go to my website, it STILL does not log me in. Only after the second load does it log me in. So maybe its not a timing issue - why does it need 2 refreshes to be able to read the cookies?
To clear up some confusion - Facebook sets the cookies (that the user is logged into Facebook), and my website reads these cookies.
This happens on every page request (logic in a user control which is on every single page)
protected void Page_PreRender(object sender, EventArgs eventArgs)
{
if (FacebookUser.IsAuthenticated) // static property, checks HttpContext.Request.Cookies
{
// log them into my website
}
}
So, on first refresh - there is nothing in HttpContext.Request.Cookies.
On second refresh, they are there.
I think the reason for this is because the FB.Init is executed on the client-side on every page request. This is what initializes the cookies. So when you first go to my website (after logging into Facebook), on the server side (where i check the cookies), this function has not yet been run.
So i think im fighting a losing battle here (trying to access a cookie server-side, that is set client-side).
EDIT 2:
Here's my init code (run on window.load):
FB.init('myapikey', 'xd_receiver.htm', null);
I'm now trying to do something like this:
FB.init('myapikey', 'xd_receiver.htm', null);
FB.getLoginStatus(function(response) {
if (!response.session) {
return false;
}
else {
window.location.reload();
}
});
But am getting a JavaScript error - "FB.getLoginStatus" is not a function. =(
This is because im using the following JavaScript library: http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US
Whereas other people say to use this one: http://connect.facebook.net/en_US/all.js
I was looking at the doco for the new JS API.
For reference to other's who stumble to this thread, here is the doco for the 'old' JS API: http://developers.facebook.com/docs/reference/oldjavascript/
So i've got this problem solved by using FB.Connect.get_status() and a window reload if the user is authenticated.
Thanks for everyone's help.
This is my "solution" to the problem if anyone else cares:
window.onload = function() {
FB.init('{0}', 'xd_receiver.htm');
FB.ensureInit(function() {
FB.Connect.ifUserConnected(onUserConnected, onUserNotConnected);
});
};
function onUserConnected() {
alert('connected!');
window.location.reload();
}
function onUserNotConnected() {
alert('not connected');
}
Of course, you should check the Forms Authentication cookie before doing window.location.reload(), otherwise the page will just keep refreshing. =)