【问题标题】:Extend auth token without refreshing the page扩展身份验证令牌而不刷新页面
【发布时间】:2011-11-18 22:17:19
【问题描述】:

用户希望在不刷新浏览器的情况下使用我的 Facebook 应用数小时。
但是令牌会在 2 小时后过期。现在我要求用户刷新页面,但这很烦人。
我不想要求离线访问权限,因为它会吓到一些用户。

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

【问题讨论】:

    标签: facebook token authentication facebook-javascript-sdk access-token


    【解决方案1】:

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

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

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

    【讨论】:

    • 但是如何更新服务器上的会话?据我了解,更新会话的唯一方法是重新加载整个页面。
    • 我不得不说,我真的不知道 facebook 应用程序是如何工作的,或者可以做什么。但通常会话由一些唯一的会话 ID 标识,通常存储在 cookie 中。每次请求到达服务器时,cookie 都会随之发送。如果 sessionID 已注册,服务器会查找(通常是缓存或文件) - 如果是这样,则有分配给此 ID 的用户详细信息。因此会话过期可能有两个原因 - cookie 过期或服务器清理它的会话注册表。首先我建议尝试定期延长 cookie 过期时间(使用 javascript)。
    • 如果它不起作用,您必须将带有用户详细信息(用户名、密码)的 ajax 请求发送到某些服务器端脚本,该脚本将重新登录并更新 cookie sessionID。而已。你这样做,你就登录了。或者你可以尝试更改服务器端会话时间,但正如我之前所说,我不知道 facebook 编程是如何进行的以及用户拥有什么权限。
    • PHP 本身无法登录,因此我无法使用它来扩展会话。相反,PHP 可以获得 URL,我将指导用户确认。这意味着我尽量避免刷新页面。
    • 我想你会因为询问他们的 Facebook 用户名和密码而受到很大的打击。
    【解决方案2】:

    我会订阅到期触发器(我认为这是 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
      }
    });
    

    【讨论】:

      【解决方案3】:

      不幸的是,我认为这在设计上是不可能的(如果您的意思是在没有用户干预的情况下发生)。如果用户仍然登录到 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;
        }
      

      这是假设您在此代码之前有一些东西,如果存在,它将处理 signed_request 参数并将值分配给 $token(您自己的显式代码或适当的 SDK 条目)。然后可以在任何需要检查 $token 是否仍然有效的地方使用显示的代码,然后再继续。

      【讨论】:

      • 但是你可以在早上打开一些游戏,在晚上“接受”一些礼物,它们会立即从你的通知中删除。所以他们以某种方式延长了访问令牌,而不是让我刷新。我想在我的应用中做同样的事情。
      • 也许我没有完全理解你想要做什么。我以为您的意思是您的用户只会与您的应用程序画布进行交互,因此您只会拥有他们第一次打开它时获得的原始令牌,该令牌将在两个小时内到期。听起来您现在正在描述通过与 Facebook 框架交互“返回”到您的应用的用户?
      • 我希望 10 小时前来过且尚未刷新浏览器的用户能够向他的朋友发送礼物。但是,如果令牌在 2 小时后过期,在其他 Facebook 游戏中怎么可能呢?
      • 当你说“没有刷新浏览器”时,你的意思是用户没有手动做任何事情(比如实际点击刷新按钮)?或者您不希望您的应用程序必须进行总页面刷新?再说一次,我想我一定没有理解您真正想要的东西,我以为您是在说您想“更新”令牌但没有进行顶级重定向。让我们换个说法——在您当前的设置中,令牌过期时会发生什么,而应该发生什么?
      • 玩家进入游戏,点击一些按钮。去某个地方 3 小时,浏览器保持打开状态。然后他点击“接受礼物”,服务器尝试从 Facebook 删除通知,但 Facebook 告诉“令牌已过期”。其他游戏以某种方式设法删除通知。
      【解决方案4】:

      尝试使用 offline_access 权限获取令牌。

      【讨论】:

      • 我不能。与添加此权限并且用户不点击“接受”时相比,与此错误相比,我失去的用户更少
      【解决方案5】:

      如果您获得 access_token 而不指定任何到期时间,它们将不会到期.. 至少要等到用户更改他的 Fb 凭据或注销您的应用程序..

      【讨论】:

      • 即如果offline_access在访问令牌创建期间在范围内,他不想使用该范围,因此访问令牌过期..
      【解决方案6】:

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

      希望对您有所帮助。

      斯帕比

      【讨论】:

      • 谢谢。我会尽快切换到 oAuth 2.0 并检查它是否有帮助。
      • 虽然我从未测试过它,但根据文档,您不能继续使用相同的代码来获取新令牌。如果您必须获得一个新代码,那么您就又回到了同一条船上。
      【解决方案7】:

      我想,我猜这是不可能的,FB 架构是不允许的。以及为什么offline_access 会出现这样的问题!!!!!!...反正我猜offline_access 是最好的最优解....

      【讨论】:

      【解决方案8】:

      一种用于锻炼的算法

      1. 请求用户许可
      2. 保存令牌
      3. 定期检查访问令牌是否即将过期
      4. 如果它在到期时,嵌入一些虚拟 iframe,重定向到 facebook 主页。 - Extend auth token without refreshing the page
      5. 这应该会刷新令牌。您可能需要生成另一个令牌或继续使用相同的令牌。无论需要什么,都可以在不刷新页面的情况下完成。

      【讨论】:

      • 实际上我在回答中提到了“虚拟 iframe”的想法。它不起作用,因为 Facebook 专门检查并阻止它。您的步骤 1-3 是正确的,但您必须执行顶级重定向而不是步骤 4。然后新令牌将可用,应用程序可以从那里开始。
      【解决方案9】:

      看看https://developers.facebook.com/docs/offline-access-deprecation/#extend_token

      基本上你用

      扩展令牌
      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 天,但我注意到类似于此处描述的错误 https://developers.facebook.com/bugs/347831145255847/?browse=search_4f5b6e51b18170786854060

      【讨论】:

        猜你喜欢
        • 2017-11-08
        • 2020-07-07
        • 2019-02-27
        • 2018-05-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-06
        • 2020-08-30
        相关资源
        最近更新 更多