我从事的一个项目将Facebook页面作为其数据源之一。它周期性地从它导入一些数据,不涉及GUI。然后我们使用一个网络应用程序来显示我们已经拥有的数据。

并非所有信息都是公开的。这意味着我必须访问一次数据,然后保存它。然而,我不知道这个过程,我还没有找到一个好的教程。我想我需要一个access_token,我怎么能从用户得到它,一步一步?用户是一个facebook页面的管理员,他是否必须添加一些我们的FB应用程序的页面?

编辑:感谢@phwd的提示。我做了一个教程,如何获得一个永久的页面访问令牌,即使offline_access不再存在。

编辑:我刚刚发现它的答案在这里:持久的FB访问令牌服务器拉FB页面信息


当前回答

除了在Vlasec回答中推荐的步骤,您还可以使用:

图形API资源管理器进行查询,例如/{pageId}?= access_token&access_token = THE_ACCESS_TOKEN_PROVIDED_BY_GRAPH_EXPLORER字段 访问令牌调试器以获取有关访问令牌的信息。

其他回答

应用程序请求限制达到(#4)- FB API v2.1及更高

这个答案把我引向了“我们的终极答案”,所以它非常相关,所以我把它附加在这里。虽然这与上述内容有关,但它是不同的,facebook似乎简化了这一过程。

当FB将api滚到v 2.1时,我们网站上的共享计数停止工作。在我们的例子中,我们已经有一个FB应用程序,我们没有使用FB登录。所以我们需要做的是获得一个FB APP令牌来发出新的请求。截至2016年8月23日。

Go to: https://developers.facebook.com/tools/explorer Select the api version and then use GET and paste the following: /oauth/access_token?client_id={app-id}&client_secret={app-secret}&grant_type=client_credentials You will want to go grab your app id and your app secret from your app page. Main FB Apps developer page Run the graph query and you will see: { "access_token": "app-id|app-token", "token_type": "bearer" } Where "app-id" and "app-token" will be your app id from your FB app page and the generated FB App HASH you just received. Next go test your new APP access token: FB Access Token tester You should see, by pasting the "app-token" into the token tester, a single app based token without an expiration date/time.

在我们的例子中,我们使用FB js sdk,所以我们改变了我们的调用,就像这样(请注意,这只得到分享计数,而不是分享和评论计数的结合,就像它以前一样):

FB.api(
    '/','GET',{
    // this is our FB app token for our FB app 
        access_token: FBAppToken,
        "id":"{$shareUrl}","fields":"id,og_object{ engagement }"
}

这是现在正常工作。这花费了大量的搜索和FB的官方错误报告,以确认我们必须开始向FB api发出令牌化请求。顺便说一句,我确实要求他们(FB)在错误代码(#4)中添加一条提到标记化请求的线索。

我刚从我们的一个开发人员那里得到另一份报告,说我们的FB评论计数也破了,因为需要新的标记化请求,所以我会相应地更新。

我做了一个PHP脚本,使它更容易。创建一个应用程序。在Graph API资源管理器中选择你的应用程序,并获得具有manage_pages和publish_pages权限的用户令牌。在关于页面的底部找到页面的ID。填写配置变量并运行脚本。

<?php
$args=[
    'usertoken'=>'',
    'appid'=>'',
    'appsecret'=>'',
    'pageid'=>''
];

echo generate_token($args);

function generate_token($args){
    $r=json_decode(file_get_contents("https://graph.facebook.com/v2.8/oauth/access_token?grant_type=fb_exchange_token&client_id={$args['appid']}&client_secret={$args['appsecret']}&fb_exchange_token={$args['usertoken']}")); // get long-lived token
    $longtoken=$r->access_token;
    $r=json_decode(file_get_contents("https://graph.facebook.com/v2.8/me?access_token={$longtoken}")); // get user id
    $userid=$r->id;
    $r=json_decode(file_get_contents("https://graph.facebook.com/v2.8/{$userid}/accounts?access_token={$longtoken}")); // get permanent token
    foreach($r->data as $d) if($d->id==$args['pageid']) return $d->access_token;
}

多亏了@donut,我设法在JavaScript中获得了永不过期的访问令牌。

// Initialize exchange
fetch('https://graph.facebook.com/v3.2/oauth/access_token?grant_type=fb_exchange_token&client_id={client_id}&client_secret={client_secret}&fb_exchange_token={short_lived_token}')
.then((data) => {
    return data.json();
})
.then((json) => {
    // Get the user data
    fetch(`https://graph.facebook.com/v3.2/me?access_token=${json.access_token}`)
    .then((data) => {
        return data.json();
    })
    .then((userData) => {
        // Get the page token
        fetch(`https://graph.facebook.com/v3.2/${userData.id}/accounts?access_token=${json.access_token}`)
        .then((data) => {
            return data.json();
        })
        .then((pageToken) => {
            // Save the access token somewhere
            // You'll need it at later point
        })
        .catch((err) => console.error(err))
    })
    .catch((err) => console.error(err))
})
.catch((err) => {
    console.error(err);
})

然后我像这样使用保存的访问令牌

fetch('https://graph.facebook.com/v3.2/{page_id}?fields=fan_count&access_token={token_from_the_data_array}')
.then((data) => {
    return data.json();
})
.then((json) => {
    // Do stuff
})
.catch((err) => console.error(err))

我希望有人能修改这段代码,因为它有点乱,但这是我能想到的唯一方法。

我根据donut的回答创建了一个小的NodeJS脚本。将以下文件存储在名为get-facebook-access-token.js的文件中:

const fetch = require('node-fetch');
const open = require('open');

const api_version = 'v9.0';
const app_id = '';
const app_secret = '';
const short_lived_token = '';
const page_name = '';

const getPermanentAccessToken = async () => {
  try {
    const long_lived_access_token = await getLongLivedAccessToken();
    const account_id = await getAccountId(long_lived_access_token);
    const permanent_page_access_token = await getPermanentPageAccessToken(
      long_lived_access_token,
      account_id
    );
    checkExpiration(permanent_page_access_token);
  } catch (reason) {
    console.error(reason);
  }
};

const getLongLivedAccessToken = async () => {
  const response = await fetch(
    `https://graph.facebook.com/${api_version}/oauth/access_token?grant_type=fb_exchange_token&client_id=${app_id}&client_secret=${app_secret}&fb_exchange_token=${short_lived_token}`
  );
  const body = await response.json();
  return body.access_token;
};

const getAccountId = async (long_lived_access_token) => {
  const response = await fetch(
    `https://graph.facebook.com/${api_version}/me?access_token=${long_lived_access_token}`
  );
  const body = await response.json();
  return body.id;
};

const getPermanentPageAccessToken = async (
  long_lived_access_token,
  account_id
) => {
  const response = await fetch(
    `https://graph.facebook.com/${api_version}/${account_id}/accounts?access_token=${long_lived_access_token}`
  );
  const body = await response.json();
  const page_item = body.data.find(item => item.name === page_name);  
  return page_item.access_token;
};

const checkExpiration = (access_token) => {
  open(`https://developers.facebook.com/tools/debug/accesstoken/?access_token=${access_token}&version=${api_version}`);
}

getPermanentAccessToken();

填入常量,然后运行:

npm install node-fetch
npm install open
node get-facebook-access-token.js

运行脚本后,浏览器中会打开一个页面,显示令牌及其有效期。

除了上面提到的方法,值得一提的是,对于服务器到服务器的应用程序,你也可以使用这种形式的永久访问令牌: app_id | app_secret 这种类型的访问令牌称为App令牌。它通常可用于调用Graph API并在应用程序后端查询公共节点。 这里提到:https://developers.facebook.com/docs/facebook-login/access-tokens