与safari的ASP.NET Facebook应用程序会话问题

时间:2012-04-30 05:06:29

标签: asp.net safari facebook-apps

目前我正在使用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 ......

任何人都有线索?

或者,无论如何我可以在Facebook应用程序中使用ASP.Net会话处理Safari吗?

非常感谢

PS。 default.aspx页面的代码

protected void Page_Load(object sender,EventArgs e)     {         if(!IsPostBack)         {             if(!string.IsNullOrEmpty(Request.Params [“signed_request”]))             {                 string signed_request = Request.Params [“signed_request”];                 if(!string.IsNullOrEmpty(signed_request))                 {                     //将签名请求拆分为编码签名和有效负载                     string [] signedRequestParts = signed_request.Split('。');                     string encodedSignature = signedRequestParts [0];                     string payload = 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);
        }
    }
}

3 个答案:

答案 0 :(得分:1)

使用无Cookie会话时,ASP.Net会自动将URL中没有会话ID的任何请求重定向到同一页面,但在URL中使用新的SessionID。但是,它重定向为GET请求,因此不会转发任何POSTED参数...因此,重定向后,您的“parameters”变量将从已解码的signed_request中丢失,因为该页面将不再具有signed_request POSTed参数

有两种可能的解决方案(我知道):

  1. 拦截Global.ascx中的初始重定向,而是在URL中使用新的SessionID进行自己的重定向...但是,在Javascript中执行此自我发布表单,其中表单还具有signed_request带有signed_request值的param。

  2. 重新启用Cookie会话,并在第一页中将FB重定向到页面。在此页面中设置一个Session变量(它将使ASP.Net设置会话cookie),然后重定向回FB。

  3. 您可能/也需要一些代码来处理任何app_data,如果这也在标签页上。

    抱歉,我无法提供更有用的代码。我为自己的工作编写了自己的处理程序,但我的工作场所现在拥有该代码!我不知道分享多少钱。

答案 1 :(得分:0)

我使用了无cookie会话,但随着初始页面的刷新,登录到登录页面的Facebook“signed_request”丢失了。

作为一种解决方法,我添加了一个HTTPModule来覆盖EndRequest()事件。如果页面是“初始页面”&amp;包含“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应该用于链接。由于不同浏览器的各种安全级别,我在cookies和Facebook上遇到了一些烦人的经历。因此,我可以忍受这些缺点。希望这有帮助!

答案 2 :(得分:0)

我知道这是一个老问题,但我遇到了完全相同的问题并找到了解决方案。 如果您在应用程序中使用SQL Server,则此解决方案可用。

使用cookieless将SessionId存储在URL中将避免cookie问题,但仍然缺少Safari中的Session问题。

好吧,您需要设置一个SQL SessionState,这将使您的应用程序与您的数据库通信以存储Sessions。这适用于Safari中的facebook canvas应用程序。

设置这很简单:

注册:运行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>

魔术就完成了!

有一些事要记住。您无法从服务器端向Facebook请求WebRequests以请求访问令牌,因为facebook会将调用重定向到“有效OAuth重定向URI”,并完全忽略请求URI中的SessionId参数。您仍然可以向API发出WebRequests,但使用Javascript进行身份验证需要是同步的。