Facebook 在不刷新页面的情况下扩展身份验证令牌

Facebook 在不刷新页面的情况下扩展身份验证令牌,facebook,token,authentication,facebook-javascript-sdk,access-token,Facebook,Token,Authentication,Facebook Javascript Sdk,Access Token,用户希望在不刷新浏览器的情况下使用我的facebook应用程序数小时。 但令牌将在2小时后过期。现在我要求用户刷新页面,但这很烦人。 我不想询问脱机访问权限,因为这会吓坏一些用户 最好的解决方案是以某种方式“重新登录”并在不刷新页面的情况下获取新令牌。 可能吗?您想过使用ajax吗?两小时后,您将检查用户是否仍处于活动状态。如果是这样,您将axax请求发送到URL,他的会话详细信息将在这里更新。例如: $(document).ready(function(){ setInterval('

用户希望在不刷新浏览器的情况下使用我的facebook应用程序数小时。
但令牌将在2小时后过期。现在我要求用户刷新页面,但这很烦人。
我不想询问脱机访问权限,因为这会吓坏一些用户

最好的解决方案是以某种方式“重新登录”并在不刷新页面的情况下获取新令牌。
可能吗?

您想过使用ajax吗?两小时后,您将检查用户是否仍处于活动状态。如果是这样,您将axax请求发送到URL,他的会话详细信息将在这里更新。例如:

$(document).ready(function(){
    setInterval('update_session()', 5500000);
})
update_session(){
    $.post({
        URL: ..., // script to update session on server
        data:{ /* username, password */ },
    })
}

服务器端只需从post或中获取用户名和密码并运行重新登录。

我会订阅到期触发器(我认为这是authResponseChange),然后自动执行另一次登录检查。这并不是一个完美的解决方案,因为它可能会自动触发弹出窗口(例如,如果他们已注销),许多浏览器可能会阻止弹出窗口。相反,当代币到期时,你可以检查他们是否需要完成弹出窗口,并在你的页面某处显示一个通知,说“Facebook需要你继续关注”,然后只从他们的响应启动弹出窗口,这将阻止弹出窗口被阻止

FB.Event.subscribe('auth.authResponseChange', function(response) {
  // do something with response
  FB.login(){
    // refresh their session - or use JS to display a notification they can 
    // click to prevent pop up issues
  }
});

不幸的是,我认为这在设计上是不可能的(如果你想让它在没有用户干预的情况下发生的话)。如果用户仍然登录到Facebook,你可以将顶级页面重定向到Facebook,它会用一个新代码(听起来你已经在这么做了)将你弹回来,但这是可能的,因为它可以检查Facebook cookie。如果您试图从服务器执行任何操作,它将被拒绝,因为该cookie将不会伴随请求。尝试从javascript调用facebook也是如此——因为您的代码运行在不同的域中,cookie不会伴随调用,facebook会拒绝它。Facebook能够知道用户是谁以及他们是否仍在登录的唯一方法就是查看cookie。唯一可能发生的情况是,浏览器本身被重定向到facebook.com域

还值得一提的是,Facebook已经阻止了唯一的逻辑解决方案,即在iframe中加载oauth url。如果您尝试它,您将看到他们检测到页面正在iframe中加载,并输出一个带有链接的页面,该链接执行顶级重定向以跳出该框架。因此,这种方法不仅不起作用,而且很明显,Facebook已经明确地将其作为其架构的一部分,使其不可能实现

编辑:如果您的意思不是完全避免刷新,而是在需要新令牌时自动刷新,则可以执行以下操作:

$status=0;
$data=@file_get_contents("https://graph.facebook.com/me?access_token=$token");
foreach ($http_response_header as $rh) if (substr($rh, 0, 4)=='HTTP') list(,$status,)=explode(' ', $rh, 3);
if ($status==200)
  {
  //token is good, proceed
  }
else
  {
  //token is expired, get new one
  $fburl="http://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=".urlencode('http://apps.facebook.com/yourapp/thispage.php');
  echo "<html>\n<body>\n<script>top.location='$fburl';</script>\n</body>\n</html>\n";
  exit;
  }
$status=0;
$data=@file\u get\u内容(“https://graph.facebook.com/me?access_token=$token”);
foreach($rh的http_响应_头)if(substr($rh,0,4)='http')list(,$status,)=explode('',$rh,3);
如果($status==200)
{
//令牌是好的,继续
}
其他的
{
//令牌已过期,请获取新令牌
$fburl=”http://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=“.urlencode('http://apps.facebook.com/yourapp/thispage.php');
echo“\n\ntop.location='$fburl';\n\n\n”;
出口
}

这是假设您在此代码之前有一个将处理已签名的_请求参数(如果存在)并为$token(您自己的显式代码或适当的SDK条目)赋值的代码。所示代码可以在任何需要检查$token是否仍然有效的地方使用,然后再继续。

尝试使用脱机访问权限获取令牌。

如果您获得访问令牌但未指定任何到期日,则这些令牌将不会到期。。
至少在用户更改其Fb凭据或注销您的应用程序之前。

我猜您正在使用iframe
signed_request
参数获取访问令牌。实现所需功能的一种方法是使用oAuth 2.0方法获取访问令牌。首先,这是一个更长的过程;您的服务器和Facebook必须交换凭据,这可能会很慢,但这意味着您将获得一个
code
,可以定期交换访问令牌,这意味着您的服务器可以定期维护会话(可能来自客户端的ajax调用)。然后将这个新的访问令牌传递给客户端,并在您的请求(礼物)对话框调用中使用它

希望有帮助


斯帕比

我猜,这是不可能的,FB架构不允许这样做。为什么离线访问会出现这样的问题!!!!!!。。。无论如何,离线访问是最好的解决方案,我想….

这是一个在这方面进行训练的算法

  • 请求用户的许可
  • 保存令牌
  • 定期检查访问令牌是否即将过期
  • 如果是过期,嵌入一些虚拟iframe,重定向到facebook主页。-
  • 这将刷新令牌。您可能需要生成另一个令牌或继续使用相同的令牌。无论需要什么,都可以在不刷新页面的情况下完成 看看

    基本上,您可以使用

    https://graph.facebook.com/oauth/access_token?             
    client_id=APP_ID&
    client_secret=APP_SECRET&
    grant_type=fb_exchange_token&
    fb_exchange_token=EXISTING_ACCESS_TOKEN 
    

    这将为您提供新的令牌和新的到期时间(应该是60天,但我注意到类似的错误,如本文所述)

    但如何更新服务器上的会话?据我所知,更新会话的唯一方法是重新加载整个页面。我不得不说,我真的不知道facebook应用程序是如何工作的,或者所有这些都可以做些什么。但通常会话是由一些唯一的会话ID标识的,这些ID通常存储在cookie中。每次请求到达服务器时,cookie都会随之发送。如果sessionID已注册,则服务器看起来(通常是缓存或文件)-如果是,则有分配给此ID的用户详细信息。因此,会话过期可能有两个原因-cookie过期或服务器清理其会话注册表。