【问题标题】:Facebook server-side authentication flow: is this the right "code?"Facebook 服务器端身份验证流程:这是正确的“代码”吗?
【发布时间】:2012-07-26 00:34:08
【问题描述】:

我在 JS 客户端上使用 FB.login 并想在服务器上验证用户的身份。因此,客户端从 facebook 获取签名请求并将其发送到服务器。服务端对句点进行拆分,将signedRequest的第二部分解码为json对象。

当我将服务器端请求发送到

时,我应该为“代码”使用什么
https://graph.facebook.com/oauth/access_token?
    client_id=YOUR_APP_ID
   &redirect_uri=YOUR_REDIRECT_URI
   &client_secret=YOUR_APP_SECRET
   &code=CODE_GENERATED_BY_FACEBOOK

我解码的 json 看起来像:

{"algorithm":"HMAC-SHA256","code":"2.AQCPA_yfx4JHpufjP.3600.1335646800.1-5702286|l11asGeDQTMo3MrMx3SC0PksALj6g","issued_at":1335642445,"user_id":"5232286"}

这是我需要的代码吗?需要B64编码吗?如果这不是代码,我应该使用什么代码?

_

我尝试过的:

我尝试使用的请求是:

https://graph.facebook.com/oauth/access_token?client_id=295410083869479&redirect_uri=https://squaredme.appspot.com/facebookredirect&client_secret=44f1TOPSECRETbb8e&code=2.AQCPA_yfx4JHpufjP.3600.1335646800.1-5702286|l11asGeDQTMo3MrMx3SC0PksALj6g

但这会返回错误:

{"error":{"message":"Error validating verification code.","type":"OAuthException","code":100}}

我不知道这是因为我使用了错误的代码,还是什么。值得注意的是,这是在我的本地开发服务器上运行的,而 squaredme.appspot.com 肯定不会解析到我的 IP。我不知道 facebook 是否会检查或检查什么 - 我假设我会收到更好的错误消息。感谢您的任何指导!

【问题讨论】:

    标签: facebook


    【解决方案1】:

    您正试图以某种方式将这两个流程结合在一起,这就是为什么事情不能正常工作的原因。

    当 facebook 将您的应用程序 url 和签名请求发送到 iframe 中时,有两个选项,最简单的一个是用户已经通过身份验证,然后签名请求将包含所有必要的数据(包括签名请求),然后你只需加载画布页面并使用 JS SDK 在那里获取访​​问令牌,但在这种情况下,不需要使用 FB.login (因为它会打开一个弹出窗口并自动关闭它),您可以使用不会惹恼用户的FB.getLoginStatus方法。

    如果用户未通过身份验证,则签名请求将丢失您使用图形 api 所需的内容。 然后您将用户重定向到auth dialog,并且由于您加载在 iframe 中,您需要返回一个使用 javascript 重定向父窗口的 html 响应,例如:

    top.location.href = "AUTH_DIALOG_URL";
    

    使用完成后(接受或拒绝应用程序),他将被重定向到您作为参数添加到身份验证对话框的“redirect_uri”。 如果用户接受了您的应用程序,那么您将在查询字符串中获得“代码”参数。 然后,您获取代码,将其与您在问题中发布的访问令牌交换,然后将用户重定向回“apps.facebook.com/YOUR_APP”。

    当页面加载时,用户已经通过身份验证,您将收到完整签名的请求。

    我希望这可以为您澄清事情,重新检查Server-Side flow 它几乎涵盖了所有内容。

    【讨论】:

    • 感谢您的解释。如果我想进行服务器端检查以验证用户是否确实已登录,我是否必须 发送对用户可见的重定向?我希望在后台默默地检查。还是认为签名请求已经证明用户确实登录了 FB,因为用户无法生成有效的签名请求?
    • 正如我所写的,正如它在documentation for the signed request 中所说的那样:“某些字段和值,例如 user_id 和 oauth_token 仅在用户授权您的应用程序时才会传递”,这意味着如果访问令牌在签名请求中,然后用户通过身份验证,您可以呈现您的画布页面。
    • Nitzan,如果我使用 Java 作为服务器端,如您所说,“加载画布页面...”的最佳方式是什么?只是一个在响应中返回 HTML 的 servlet?对我来说似乎并不优雅。谢谢。
    • 什么对你来说是优雅的?这就是 servlet 的作用,它们返回动态内容,可以是 html、图像、pdf 文件等。有什么问题?
    【解决方案2】:

    我也遇到了一些麻烦,然后我在 StackOverflow 中找到了解决方案。 facebook提供了两种“代码”。一个来自客户端流生成的 cookie 中的 signedRequest。 Facebook 的 JS SDK 处理这些代码并在不告诉我们任何内容的情况下获取访问令牌。

    当您导航到 OAuth URL(服务器端流动)。使用此代码,您可以转到令牌 URL 并获取您的访问令牌。

    当您使用服务器端流程时,您需要在 OAuth URL 和 Token URL 中指定重定向 URI,并且它们必须完全相同,因此可以缺少斜杠或查询字符串很多问题。

    代码彼此不同。当您同时使用这两种东西时,似乎不可能使用 cookie 的 signedRequest 中的代码获取访问令牌。

    但是,事实并非如此。神奇之处在于:signedRequest 中的代码与 NO URI 相关联,因此只要 redirect_uri 是必填字段,您只需在导航到 Token URL 时将其传递为空白即可。

    所以最终的解决方案是:从cookie中获取signedRequest,在你的服务器中解析得到代码,然后读取Token URL

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

    它看起来像一个 hack,所以我不知道它会工作多久,但它现在正在工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 2011-12-29
      • 2012-05-31
      • 1970-01-01
      • 1970-01-01
      • 2015-06-10
      • 2012-06-05
      相关资源
      最近更新 更多