Проблема сеанса приложения ASP.NET Facebook с сафари

В настоящее время я работаю над приложением Facebook, и оно разработано с использованием ASP.NET.

Это приложение отлично работает с IE (7,8 и 9) FF и Chrome.

Первая страница - default.aspx, и она будет обрабатывать аутентификацию, а затем перенаправлять на home.aspx.

Теперь единственная проблема заключается в том, что Safari не принимает междоменные файлы cookie. Я изменил файл web.config и добавил его, чтобы избежать использования файлов cookie.

После этого URL переходит к http://www.testdomain.com/(S(gvsc2i45pqvzqm3lv2xoe4zm))/default.aspx

Просто невозможно автоматически перенаправить с default.aspx на home.aspx ...

У кого-нибудь есть подсказка?

Или я могу работать с Safari с сеансом ASP.Net в приложении Facebook?

Тонны благодарности

PS. Код со страницы default.aspx

protected void Page_Load (отправитель объекта, EventArgs e) {if (! IsPostBack) {if (! string.IsNullOrEmpty (Request.Params ["signed_request"])) {string signed_request = Request.Params ["signed_request"]; if (! string.IsNullOrEmpty (signed_request)) {// разделить подписанный запрос на закодированную подпись и строку полезной нагрузки [] signedRequestParts = signed_request.Split ('.'); строка encodedSignature = signedRequestParts [0]; строка полезной нагрузки = signedRequestParts [1];

                // decode signature
                string signature = decodeSignature(encodedSignature);
                // calculate signature from payload
                string expectedSignature = hash_hmac(payload, Facebook.FacebookApplication.Current.AppSecret);

                if (signature == expectedSignature)
                {
                    // signature was not modified
                    Dictionary<string, string> parameters = DecodePayload(payload);
                    if (parameters != null)
                    {
                        string UserId = parameters["user_id"];
                        Session.Add("UserId", _SystemUser.SystemUserId);
                        Session.Add("Username", _SystemUser.Username);
                        Response.Redirect("Home.aspx?user_id=" + UserId);
                    }
                }
            }
        }

        if (!String.IsNullOrEmpty(Request["error_reason"])) // user denied your request to login
        {
            logger.Debug("Error Reason: " + Request["error_reason"]);
            //User denied access
        }

        if (String.IsNullOrEmpty(Request["code"])) // request to login
        {
            string url1 = String.Format("https://www.facebook.com/dialog/oauth?client_id={0}&redirect_uri={1}&scope={2}", Facebook.FacebookApplication.Current.AppId, callbackUrl, ext_perms);
            Response.Redirect(url1);
        }
    }
}

person MagicYang    schedule 30.04.2012    source источник


Ответы (3)


При использовании сеансов без файлов cookie ASP.Net автоматически перенаправляет любые запросы без идентификатора сеанса в URL-адресе на ту же страницу, но с новым идентификатором сеанса в URL-адресе. Однако он перенаправляет как запрос GET и, таким образом, не пересылает какие-либо параметры POSTED ... поэтому после перенаправления ваша переменная "parameters" из декодированного signed_request будет отсутствовать, потому что страница больше не будет иметь параметр POSTed signed_request .

Есть два возможных решения этого (о которых я знаю):

  1. Перехватите начальное перенаправление в Global.ascx и вместо этого выполните собственное перенаправление с новым идентификатором сеанса в URL ... НО, сделайте это как форму самостоятельной публикации в Javascript, где форма также имеет параметр signed_request со значением подписанный_запрос.

  2. Включите сеансы файлов cookie снова и на своей первой странице перенаправьте из FB на страницу. На этой странице установите переменную сеанса (которая заставит ASP.Net установить файл cookie сеанса), а затем перенаправить обратно в FB.

Вам может / понадобится код для обработки любых app_data, если он тоже находится на странице вкладки.

Извините, я не могу быть более полезным с точки зрения кода. Я написал свои собственные обработчики для своей работы, но теперь мой рабочий код владеет этим кодом! Я никогда не знаю, чем можно поделиться.

person Owen Berry    schedule 30.04.2012
comment
Я бы тоже добавил; Я использую пользовательский агент, чтобы проверить, использует ли пользователь Safari, прежде чем выполнять какой-либо код перенаправления! Не хочу без надобности замедлять работу пользователей! :-) - person Owen Berry; 01.05.2012

Я использовал сеанс без файлов cookie, но поскольку начальная страница обновлялась, сообщение Facebook "signed_request", отправленное на целевую страницу, было потеряно.

В качестве обходного пути я добавил HTTPModule, чтобы переопределить событие EndRequest (). В случае, если страница является "начальной страницей" и содержит "signed_request" POSTed, значение добавляется как строка запроса. На странице мы проверим значение строки запроса и установим его в сеанс, который будет использоваться в приложении.

EndRequest выглядит следующим образом:

void context_EndRequest(object sender, EventArgs e)
{
    HttpContext cntxt = HttpContext.Current;
    const string paramname = "signed_request";
    const string initialPage= "/startapp.aspx";
    if ((String.Compare(cntxt.Request.Url.AbsolutePath, initialPage, true) == 0) && (!String.IsNullOrEmpty(cntxt.Request[paramname])))
    {
        string strQuerySignedReq = paramname+"=" + cntxt.Request[paramname];
        if (cntxt.Response.RedirectLocation.Contains(".aspx?"))
            cntxt.Response.RedirectLocation = cntxt.Response.RedirectLocation + "&" + strQuerySignedReq;
        else
            cntxt.Response.RedirectLocation = cntxt.Response.RedirectLocation + "?" + strQuerySignedReq;
    }
}

Начальная страница - "startapp.aspx", событие загрузки будет:

protected void Page_Load(object sender, EventArgs e)    
{
   signed_request = Request.QueryString["signed_request"];
}

Недостаток кода в том, что EndRequest () будет выполняться для всех запросов. Кроме того, для ссылок следует использовать только относительный URL. У меня было несколько неприятных ситуаций с файлами cookie и Facebook из-за разного уровня безопасности в разных браузерах. Следовательно, я могу жить с недостатками. Надеюсь это поможет!

person sreecheck    schedule 23.05.2012

Я знаю, что это старый вопрос, но у меня была точно такая же проблема, и я нашел решение. Решение здесь работает, если вы используете в своем приложении SQL Server.

Использование cookieless для хранения вашего SessionId в URL-адресе позволит избежать проблемы с cookie, но по-прежнему будет отсутствовать проблема Session в Safari.

Что ж, вам нужно установить SQL SessionState, это заставит ваше приложение взаимодействовать с вашей базой данных для хранения сеансов. Это будет работать для приложений холста facebook в Safari.

Установить это просто:

Регистрация: запустить aspnet_regsql.exe (в C: /Windows/Microsoft.NET/Framework/'Framework version '/) Проверить параметры в https://msdn.microsoft.com/en-us/library/ms229862.aspx (основные из них -S –ssadd)

По тому же пути находится скрипт InstallSqlState.SQL. Запустите его на своем сервере базы данных.

Теперь установите этот тег в свой файл Web.Config:

<configuration>
  <system.web>
    <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="120" cookieless="true" />
  </system.web>
</configuration>

И волшебство свершилось!

Есть что вспомнить. Вы не можете выполнять WebRequests для facebook со стороны сервера для запроса токенов доступа, потому что facebook перенаправляет вызовы на «действительные URI перенаправления OAuth» и полностью игнорирует параметры SessionId в URI запроса. Вы по-прежнему можете делать WebRequests для API, но аутентификация должна быть синхронизированной с использованием Javascript.

person Pedro Nunes    schedule 23.10.2015
comment
Очень признателен за ваш ответ. В то время я фактически не нашел никаких решений. Но я верю, что ваш сработает. Попробую твое, если у меня будет возможность. - person MagicYang; 26.10.2015