31

我想让用户使用他们的 Facebook ID 登录我的网站,而无需重新加载页面。这就是我使用Facebook Javascript SDK的原因。该方案描述了使用此 SDK 的授权流程: 在此处输入图像描述

在流程结束时,我知道用户已登录并且我知道他们的 Facebook ID。然后我可以通过这个 ID 在我的数据库中注册他们,然后让他们使用它来登录。

然而,这似乎非常不安全。为了让我的服务器端脚本知道用户的 ID,我必须通过 AJAX 发送它。但是,我无法知道尝试登录的是否是 ID 的所有者。任何人都可以发送带有 ID 的 POST 请求(尤其是获取另一个用户 ID 的人)。

我目前的想法是让用户像往常一样通过JS SDK登录,通过AJAX将ID和Access Token发送到服务器,然后在PHP脚本中使用cURL来确保用户实际登录。

这是要走的路,还是我忽略了更好的选择?

4

2 回答 2

27
  1. 您不需要通过 ajax 推送用户 ID。您应该在服务器端使用保存签名请求的 fbsr_{app_id} cookie。使用 FB 发布的“秘密”app_secret 解析此签名请求以获取“用户 ID”。注意:成功的解析还表明 FB 提供的 cookie 数据没有被篡改。

  2. 解析 signed_request 后,您还应该获得“issued_at”时间。检查此时间是否在最后 10 分钟内。通过这样做,您知道登录请求到达您的服务器,因为用户(使用 user_id)使用客户端 SDK。(参考:http: //developers.facebook.com/roadmap/completed-changes/

  3. 您应该立即将此代码交换为 access_token。如果失败(FB 会给你一个 OAuthException 类型的错误消息),这意味着在用户登录 facebook 和你收到登录请求之间存在不自然的延迟。

通过第 2 步,您可以阻止使用旧 fbsr_cookie 的攻击尝试。如果用户(来自 user_id)已经有您的帐户,那么您可能希望在此处停止并登录该用户。但是,在某些情况下您的 app_secret 可能会受到威胁。要处理这种情况,您应该按照步骤 3 进行操作,因为access_token 的代码交换只能发生一次,并且在问题发生后 10 分钟内发生。如果用户没有您网站的帐户,那么您无论如何都需要第 3 步来使用 access_token 从 FB 检索其他必要的用户数据,例如姓名、电子邮件等。

因此,只有在这 10 分钟的安全间隙内,其他人才能窃取受害者的 cookie 并试图进行攻击。如果您对这个安全漏洞不满意,您应该迁移到服务器端身份验证。该决定取决于您存储的用户信息的敏感性。而且您不会损害任何转移到服务器端身份验证的东西,您可以同时继续将客户端方法用于其他事情。

于 2013-01-08T23:38:43.193 回答
9

通过 JS SDK 登录用户后,将设置一个包含凭据信息的特殊 cookie(如果我是正确的,则使用您的密钥编码)。然后可以通过PHP SDKgetUser()方法使用此信息。

只要您的 API(您的 ajax 端点)与您的应用程序位于同一个域中,您就应该在用户请求您的服务器时收到此 cookie。

当然,您需要确保正确设置了 Javascript SDK,并且您使用了cookie: trueconfig 选项,并且您提供了一个有效的channel文件。如果不满足这些要求,您可能会在 IE 和 Safari 中的跨域通信和 3rd 方 cookie 方面遇到一些问题。

您还可以检查这个相关问题:A proper approach to FB auth

于 2013-01-06T21:30:47.833 回答