Facebook Connect - единый вход вызывает бесконечный цикл :( - PullRequest
1 голос
/ 17 сентября 2010

У меня есть веб-приложение Facebook Connect (FBML), которое уже давно работает.

Все работает хорошо, однако пользователи сообщают о проблемах с помощью единого входа (и я видел проблемуна своем компьютере, но не смогли выполнить локальную репликацию).

В FBC существует «событие», в которое вы можете подключиться, чтобы автоматически определить, прошел ли пользователь аутентификацию в Facebook.

Это достигается с помощью этого:

FB.Connect.ifUserConnected(onUserConnected, null);

Затем функция onUserConnected может делать все, что ей нужно, для попытки единого входа.

Для меня то, что я делаю, этоAJAX-вызов на сервер, чтобы узнать, есть ли у пользователя активная учетная запись веб-сайта (на основе данных Facebook - идентификатор пользователя, который я сохраняю в моей системе при подключении).

Если они это сделают, я показываю модальное диалоговое окно jQuery («Соединение с Facebook») и выполняю window.location.reload ().

Затем сервер запускает и выполняет SingleПодпишись.Этот код выполняется на каждой странице:

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();
                }
            }
        }

У меня никогда не возникало проблем с этим, но пользователь сообщает о «бесконечном» цикле, где отображается диалоговое окно, обновляется окно, отображается диалоговое окно,окно обновляется и т. д.

По сути, мой AJAX-вызов говорит, что пользователь существует, но мой единый вход - нет.

В это трудно поверить, потому что код очень похож:

Это веб-служба AJAX:

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;
                        }
                    }
                }
            }

Так что, если ответ этого WS 'true', я делаю window.location.reload ();

Таким образом, я понятия не имею, в чем проблема (поскольку я не могу повторить), похоже, что единый вход не добавляет файл cookie проверки подлинности с помощью форм в поток ответов, или Response.Redirect (Request.RawUrl) нетправильная перезагрузка cookie.

Как другие справляются с этим?

Вот что должно произойти:

  1. Пользователь входит в Facebook (на самом Facebook)
  2. Пользователь заходит на мой сайт (который был предыдущимавторизован)
  3. Мой сайт сравнивает FBID с FBID в моей БД и регистрирует их.

Мой сайт является приложением ASP.NET 4.0 Web Forms, использующим "старый API JavaScript Facebook Connect (FeatureLoader.js) и проверка подлинности с помощью форм.

Единственное другое решение для вызова / окна AJAX, о котором я могу подумать, - это AJAX UpdatePanel.

Можеткто-нибудь мне помочь?

РЕДАКТИРОВАТЬ

Кроме того, я понимаю, что я также могу использовать 'reloadIfSessionStateChanged':true для перезагрузки (которая останавливает бесконечный цикл), нопроблема в том, что я не могу показать свой красивый модный диалог.

1 Ответ

1 голос
/ 17 сентября 2010

Итак, я обнаружил пару проблем.

Во-первых, я не должен устанавливать постоянный файл cookie:

FormsAuthentication.SetAuthCookie(membershipUser.UserName, true);

Мы должны делать это только тогда, когда пользователь ставит галочкукак «Помни меня».

Во-вторых, я проверял состояние FB Auth на каждой странице на сервере, поэтому это могло быть не синхронизировано на стороне клиента.

Здесьэто мое новое решение, которое лучше и имеет отказоустойчивость для страшного «бесконечного цикла».

Я больше не проверяю статус FB Auth на сервере, я делаю на клиенте:

FB.Connect.ifUserConnected(onUserConnected, null); // runs on every page request, on client-side

В функции onUserConnection я делаю следующее:

  1. Вызовите веб-службу, чтобы узнать, может ли пользователь автоматически войти в систему (тот же WS, что и выше)
  2. Если все в порядке, проверьтеспециальный файл cookie "Single Sign On" не был установлен.
  3. Если он не был установлен, перенаправьте его на FacebookSingleSignOn.aspx.

FacebookSingleSignOn.aspx выполняет следующие действия:

  1. Подписывает пользователя с помощью проверки подлинности с помощью форм (как и выше)
  2. Создает специальный файл cookie "Single Sign On", чтобы указать, что была предпринята попытка SSO
  3. Перенаправляет на домашнюю страницу

Итак, в пункте 3 выше - этогде бесконечный цикл "мог" произойти.(поскольку onUserConnected будет запущен снова)

Но теперь это (я надеюсь) невозможно, поскольку он будет пытаться выполнить единый вход, только если они еще не пытались.

Iочистите файл cookie единого входа в действии «Выход из Facebook».

Теперь работает хорошо, логика имеет смысл - и это делается на стороне клиента (где и должно быть, поскольку именно здесь FB творит чудеса).

Надеюсь, это поможет кому-то еще.

...