Hi Guys,
I have a Facebook Connect (FBML) web application that has been live for a while now.
All is working well, however user's are reporting issues with the single sign on (and i have seen the issue on their computer, but have not been able to replicate locally).
With FBC, there is a "event" you can hook into to automatically determine if the user is authenticated to Facebook.
That is achieved via this:
FB.Connect.ifUserConnected(onUserConnected, null);
The onUserConnected function can then do whatever it needs to attempt a single sign on.
For me, what i do is a AJAX call to the server to see if the user has an active website account (based on the Facebook details - user id, which i store in my system when they connect).
If they do, i show a jQuery modal dialog ("Connecting with Facebook") and do a window.location.reload().
The server then kicks in, and does the Single Sign On. This code is executed on every page:
public static void SingleSignOn(string redirectUrl)
{
if (!HttpContext.Current.Request.IsAuthenticated) // If User is not logged in
{
// Does this user have an Account?
if (ActiveFacebookUser != null)
{
// Get the user.
var saUser = tblUserInfo.GetUserByUserId(ActiveFacebookUser.IdUserInfo);
if (saUser != null)
{
// Get the Membership user.
MembershipUser membershipUser = Membership.GetUser(saUser.UserID);
if (membershipUser != null && membershipUser.IsApproved)
{
// Log Them Automically.
FormsAuthentication.SetAuthCookie(membershipUser.UserName, true);
// At this point, the Forms Authentication Cookie is set in the HTTP Response Stream.
// But the current HTTP Context (IsAuthenticated) will read HTTP Request Cookies (which wont have the new cookie set).
// Therefore we need to terminate the execution of this current HTTP Request and refresh the page to reload the cookies.
HttpContext.Current.Response.Redirect(
!string.IsNullOrEmpty(redirectUrl) ? redirectUrl : HttpContext.Current.Request.RawUrl,
true);
}
else
{
HandleUnregisteredFacebookUser();
}
}
else
{
HandleUnregisteredFacebookUser();
}
}
else
{
HandleUnregisteredFacebookUser();
}
}
}
I have never experienced an issue with this, but user's are reporting an "infinite" loop where the dialog gets shown, the window is refreshed, dialog is shown, window is refreshed, etc.
Basically, my AJAX call is saying the user exists, but my single sign on isn't.
Which is hard to believe because the code is very similar:
This is the AJAX Web Service:
if (!HttpContext.Current.Request.IsAuthenticated) // If user is not yet authenticated
{
if (FacebookConnect.Authentication.IsConnected) // If user is authenticated to Facebook
{
long fbId;
Int64.TryParse(Authentication.UserId, out fbId);
if (fbId > 0)
{
tblFacebook activeUser = tblFacebook.Load(facebookUniqueId: fbId);
if (activeUser != null && activeUser.IsActive) // If user has an active account
{
return true;
}
}
}
}
So if the response of this WS is 'true', i do a window.location.reload();
So i have no idea what the issue is (as i cant replicate), sounds like the Single Sign On isn't adding the Forms Authentication cookie properly to the response stream, or the Response.Redirect(Request.RawUrl) isn't reloading the cookie properly.
How do other's handle this?
This is what should happen:
- User logs into Facebook (on Facebook itself)
- User comes to my site (which has been previously authorised)
- My site compares the FBID with the FBID in my DB, and signs them in.
My site is an ASP.NET 4.0 Web Forms application, using the "old" Facebook Connect JavaScript API (FeatureLoader.js), and Forms Authentication.
The only other solution to an AJAX call/window.reload i can think of is an AJAX UpdatePanel.
Can anyone help me out?
EDIT
Also, i realise that i can also use 'reloadIfSessionStateChanged':true
to do the reload (which stops the infinite loop), but the problem with this is i cannot show my nice fancy dialog.