1

我有一个最初在 PHP 中编码为服务器端身份验证的应用程序。

但是,我希望客户端对我的服务器进行 AJAX 调用,然后基于 Facebook userId 在我的数据库中执行一些查询。我不能只接受一个userId变量,因为任何人都可以欺骗它,所以我认为我需要访问用户的accessToken。

但是,这是对服务器上 PHP 文件的 AJAX 调用,我无法使用与示例中相同的服务器端身份验证方法。

所以我认为客户端需要通过 AJAX 调用传递一个 FB 访问令牌,然后我在服务器端验证该访问令牌,然后使用它来获取用户的 id 和附加信息。

但是,如果我使用服务器端身份验证,客户端实际上永远不会从 Facebook 检索其访问令牌,只有服务器拥有它,这意味着客户端无法传递访问令牌。

我的问题是:一旦我进行了原始的服务器端验证,我是否应该根据 cookie 在服务器端存储访问令牌,然后以这种方式获取 access_token?

或者,对于 Facebook 应用程序是否有更好的做法,这样我就不必担心通过 cookie 欺骗泄露访问令牌?

4

1 回答 1

3

首先,您不应将访问令牌存储在 cookie 中或通过 ajax 调用发送。访问令牌是必须始终不可见的敏感数据。

我不知道这是否是最好的方法,但我总是使用signedRequest。这是发送到您的服务器的安全数据,因为它是使用您的应用程序机密加密的,没有人知道...

如果您将 signedRequest(来自 FB JS SDK)传递到您的服务器,则可以检索有效的访问令牌。在 PHP 中,它看起来像这样,假设您通过 POST 传递 signedRequest:

$signed_request = $_POST['signedRequest'];
$data = parseSignedRequest($signed_request);
$token_url= 'https://graph.facebook.com/oauth/access_token?' .
            'client_id=' . YOUR_APP_ID .
            '&redirect_uri='  . // when using the JS signedRequest, leave this blank
            '&client_secret=' . YOUR_APP_SECRET .
            '&code=' . $data["code"];

$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token']; // here is your access token

您将需要这些功能:

function parseSignedRequest($signed_request) {
    list($encoded_sig, $payload) = explode('.', $signed_request, 2);
    // decode the data
    $sig = base64UrlDecode($encoded_sig);
    $data = json_decode(base64UrlDecode($payload), true);

    if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
        return 'Unknown algorithm. Expected HMAC-SHA256';
    }

    // check sig
    $expected_sig = hash_hmac('sha256', $payload, YOUR_APP_SECRET, $raw = true);
    if ($sig !== $expected_sig) {
        return 'Bad Signed JSON signature!';
    }
    return $data;
}

function base64UrlDecode($input) {
    return base64_decode(strtr($input, '-_', '+/'));
}

当然,如果您将访问令牌存储在数据库中,则无需通过此操作,但请注意令牌过期。

如果用户已经授权您的应用程序并登录 Facevook,您可以从 cookie 中检索 signedRequest $_COOKIE[('fbsr_' . YOUR_APP_ID)],但我不太相信这些数据......

于 2012-08-02T18:14:40.757 回答