【问题标题】:Facebook Authentication ImplementationFacebook 身份验证实现
【发布时间】:2011-07-25 14:26:11
【问题描述】:

我正在开发一个完全使用 facebook 身份验证的项目(不存在自定义身份验证实现)。项目使用 PHP 进行服务器端脚本。我四处寻找实现快速和安全的身份验证机制,但我找不到关于这个主题的任何详细描述。 Facebook 的文档薄弱,仅提供基本信息。

哪种身份验证方法合适?有一个 Javascript SDK 和 PHP SDK。据我了解,我必须使用 Javascript SDK 登录,然后使用 PHP SDK 我将检查我的数据库以验证凭据。但是在 PHP SDK 中使用 Graph API 很慢。有没有更好的方法来验证会话?

我需要在每个请求上检查会话服务器端 (PHP-SDK) 吗?

【问题讨论】:

    标签: php authentication facebook-graph-api facebook-php-sdk facebook-javascript-sdk


    【解决方案1】:

    与我见过的任何其他方法相比,我最终为我的应用程序所做的工作非常简单且相对较快。

    1. 检查 signed_request 是否存在,如果存在则解析它。如果没有,请在 PHP 中将 $login 标志设置为 1
    2. 我检查用户的会话/cookie 以查看用户之前是否已通过应用程序的身份验证(稍后将返回此内容。如果为空,请将 $login 设置为 1。
    3. 如果登录标志设置为 1,则将用户发送到安装 URL。
    4. 用户安装应用程序并被发送到连接器页面。此页面用于获取 access_token 并为用户生成会话/cookie。这意味着您可能不需要在用户会话的整个生命周期内检查此 access_token 的有效性。 offline_access 也创造了新的机会。您也可以将 access_token 存储在您的数据库中。
    5. 每当您接到 Facebook 的呼叫时,请检查异常,如果遇到身份验证异常,请清除用户的会话和 cookie。下次它会强制他们更新他们的 access_token,即使这个过程对用户是不可见的。

    我已经在我的应用程序上执行了此操作,在大多数情况下,这意味着我不必向 FB 查询以查看 access_token 的有效性,也不必在每次页面视图中不断获取它。我们的目标是减少应用的延迟,但 Facebook 是最大的延迟来源,这样做大大减少了延迟。

    【讨论】:

      【解决方案2】:

      回答我自己的问题:

      我使用 Javascript SDK 来检查 facebook 身份验证是否可用。

      • 如果 fb 身份验证正常且我的应用程序未通过身份验证,我会向用户提供一个预先填写的 facebook 注册表单。
      • 如果 fb 身份验证不正确,我会显示一个 facebook 登录按钮。

      注册插件授权我的应用程序,我调用我的 fblogin.php 以使用 PHP SDK 检查此信息。当 PHP SDK 验证授权时,它将此信息存储在会话变量中。因此无需对每个请求都检查 fb 身份验证。

      登录按钮的作用与注册插件相同。这些方法共享相同的服务器端功能,但表示方式不同。

      为了捕捉 facebook 注销状态,我使用 Javascript SDK 来验证每个请求的 facebook 身份验证。如果用户注销,我的 js 代码调用 fblogout.php 并且当前会话被破坏。这种方法有缺陷。如果用户没有明确地从我的网站注销,攻击者可以代表用户做任何事情,只在同一台机器上禁用 js。

      我找不到响应时间更快的更好解决方案。

      【讨论】:

      • 看起来你已经弄清楚了大部分。你是什​​么意思“攻击者可以代表用户做任何事情,只在同一台机器上禁用 js”?其含义应该与独立登录系统相同(剩余 cookie 的使用方式大致相同)。如果您的应用程序需要更高的安全性,推荐的方法是使用fbsr cookie(我希望您使用OAuth)仅触发一种“伪登录”并创建您自己的会话cookie。然后,您的应用程序可以随意控制它的失效。
      • 看看我的article,它可能对你使用注册插件有所帮助。
      【解决方案3】:

      您可以使用其中一种或两种。

      您可以使用 PHP SDK 生成相关的 URL 以将人们发送到。只需将其放在链接上即可。 或者您可以使用 Javascript 制作 Facebook 默认登录按钮。

      之后,您可以使用其中一个来维护和验证会话。

      我通常使用 PHP 来处理 oAuth 密钥的繁琐工作,并使用 JavaScript SDK 来制作漂亮的 Facebook 按钮和一些次要的不太重要的图形调用以进行会话监控。

      任何涉及我推送到 PHP 的繁重或多个图形调用的任何内容。

      但是你可以灵活地做你想做的事。您不必使用 JavaScript SDK 登录。

      是否要验证每个页面加载是否由您决定。

      如果会话结束,我倾向于使用 Javascript SDK 来处理它,并且喜欢 Berk。调用页面重定向到注销脚本。

      【讨论】:

        【解决方案4】:

        从最新版本开始,PHP 和 JS SDK 现在都能够访问相同的用户会话(使用 JS PHP [而不必同时使用这两种方法] 登录)。查看this blog post 以获得更详细的说明和示例。

        如果您担心安全问题,也许您可​​以使用session_set_cookie_params() 将会话 cookie 设置为更快过期。

        【讨论】:

          【解决方案5】:

          首先,提醒您,您不仅需要保存 access_token,而且理想情况下,您希望将用户的 facebook uid 与访问令牌一起保存。这是因为通常情况下,您需要在 API 调用中包含 uid 和访问令牌。

          第二,来自Facebook Documentation

          注意:如果应用没有请求offline_access权限, 访问令牌是有时间限制的。有时限的访问令牌也得到 当用户退出 Facebook 时无效。如果应用程序有 获得用户offline_access权限,访问令牌 没有有效期。但是,只要用户使用它就会失效 更改他/她的密码。

          第三,有access_token和uid的目的,是为了执行一个API调用吧?从那里开始。 如果只有access_token(以某种方式)无效,是否进行身份验证。 那么如何检查其是否有效?好吧,您可以使用 cURL (Reference) 或 Proxy Library(但您可能需要稍微修改一下,因为它最初是为 CI 编写的)来进行 API 调用作为验证过程。示例(*叹气,使用我的代理库)...

          // Suppose we are try to publish a status from our fb app
          // $access_token hold the user access_token, which you saved into your database
          // $uid hold the user facebook uid, which you saved into your database
          $proxy = new Proxy;
          // This is equal with perform regular HTTP POST request with cURL
          $api_call = $proxy->http('post','https://graph.facebook.com/'.$uid.'/feed', array('access_token' => $access_token,'message' => 'foo'));
          
          // Now we can validate...
          // If the API success, it will be returned a post id, with json format
          // if not, it will be outputing json like...
          // "{"error":{"type":"OAuthException","message":"Invalid OAuth access token."}}"
          // so...
          $result = (array) json_decode($api_call);
          if(array_key_exists('error', $result))
          {
              // Here you can perform an oAuth authentification, to get fresh access_token and update your database
              // ...
              // After it done, process the previous api call with valid access_token
              $proxy->http('post','https://graph.facebook.com/'.$uid.'/feed', array('access_token' => $access_token,'message' => 'foo'));
          }
          

          【讨论】:

            【解决方案6】:

            Facebook Connect 文档相当有限。它并没有真正告诉你它在做什么,而只是告诉你如何去做。我个人不使用任何一个 SDK。我已经为我的开发项目构建了自己的框架。

            本教程中的 SDK 和 JavaScript 都已过时,IMO。

            如果您想坚持使用其中一种 FB SDK,我的建议是。仅当您的 Graph API 查询等通过 Ajax 发送到 PHP 后端时,才使用 JS SDK。否则坚持使用 PHP SDK。

            简介

            Facebook 使用 oAuth v2。他们描述了两种不同的流程方法……服务器端和客户端。这将与针对 oAuth v2 服务进行身份验证的任何其他应用程序一样实现。他们都做同样的事情。唯一的区别可能是您可以使用 'code' 作为 request_type 来获取授权码,以便将来获取令牌。

            身份验证

            就 FB Connect 而言,您的脚本需要确保在需要身份验证时拥有身份验证令牌或身份验证代码。如果你没有,那么你需要得到它。您可以使用身份验证代码或令牌的存在作为显示 FB 按钮(登录或注销)的条件。

            将用户重定向到 oAuth 进行身份验证。 Facebook 将他们的 oAuth 实现捆绑到他们的对话 API 中。有关 oAuth 对话框的更多信息,请点击此处:http://developers.facebook.com/docs/reference/dialogs/oauth/

            您可以将可选的状态参数用于诸如 CSRF 保护之类的东西。它在处理后保留它的值,并与回调一起作为 GET 参数发送。

            应用程序交互

            基本上,您将按照通常的方式编写应用程序。区别在于:

            1. 您的用户数据库不再存储密码,只存储 FB UID。此外,根据 FB Dev ToS,您确实无法存储任何用户信息。如果要存储用户信息,则需要从用户那里获取。您可以使用 FB 信息为他们填充此信息,您只需要他们提交即可。
            2. 您的注册方法将不再有表单前端发布。当经过身份验证的用户在数据库中没有条目时将调用它。

            API 交互

            如果您使用代码而不是令牌,则需要通过发送代码来请求令牌。这是通过 Graph API oauth 完成的。除了在他们的身份验证教程中之外,这部分根本没有记录。 http://developers.facebook.com/docs/authentication/

            使用您的访问令牌,无论您使用哪种方法获取它。您现在可以根据需要查询 Graph API。这将返回一个 JSON 编码的对象。

            结论

            就快速且安全的实施而言,Facebook PHP SDK 可以胜任。它处理我在这里介绍的所有内容,包括 CSRF。如何去学习它,我还没有找到合适的文档。要么一切都过时,要么作者并不真正了解,并且正在停止使用其他教程。

            最好的办法是深入研究这些库并弄清楚它是如何为自己工作的。做一些试验和错误,实验。

            我学习的方式是为它编写自己的框架。我建议你这样做。如果您愿意,可以扩展 Facebook SDK 类。它确实是有限的,但它可以为您提供所需的一切。我将最常用的 API 调用也放入其中。我现在有一个从我的库驱动的非常快速和简单的最终结果。

            【讨论】:

              【解决方案7】:

              我认为您不需要实现 SDK。

              1,您需要获得用户的许可才能访问他/她的数据。因此,您需要将它们重定向到 Facebook。它是 php 中的几行 (3-5) 代码。

              https://graph.facebook.com/oauth/authorize?
              client_id=YOUR_APP_ID&scope=email&redirect_uri=APP_URL 
              

              2、当用户回到你的站点时,带上$_GET['code']

              http://YOUR_URL?code=A_CODE_GENERATED_BY_SERVER
              

              3、你必须通过Facebook get请求解码这段代码,并获取access_token。

              https://graph.facebook.com/oauth/access_token?
              client_id=YOUR_APP_ID&redirect_uri=YOUR_URL&
              client_secret=YOUR_APP_SECRET&code=THE_CODE_FROM_ABOVE
              

              3,获得 access_token 后,只需根据需要运行 /me?access_token GET 请求,以检查用户是否仍然存在。

              4,您可以存储Facebook ID。

              我认为这是最快的方法。据我所知,javascript sdk 使用弹出窗口,大多数浏览器都被阻止。

              这里的流程已经足够详细了:http://developers.facebook.com/docs/authentication/

              【讨论】:

              • 您的第一个网址不正确。用户通过身份验证后使用图形 api。图 api 中 oauth 的 access_token 部分用于将身份验证代码转换为身份验证令牌。
              猜你喜欢
              • 2018-02-24
              • 1970-01-01
              • 2015-01-21
              • 1970-01-01
              • 1970-01-01
              • 2022-01-25
              • 1970-01-01
              • 2015-08-10
              • 2017-11-27
              相关资源
              最近更新 更多