尝试使用 Graph API Explorer 中生成的访问令牌会产生不正确的权限

Trying to use Access Token generated in the Graph API Explorer yields incorrect permissions

我创建了一个 C# 应用程序,它向 Facebook Graph API 发出 GET/POST 请求,以自动将图像上传到页面时间轴。

该应用程序是一个控制台应用程序,因此就登录 facebook 以检索访问令牌而言,用户登录是不行的,相反,我使用 Graph API 生成令牌,我的应用程序扩展了它. 这工作了大约 12 个小时,直到现在所有权限都是错误的。

当我在 Graph Explorer 中生成令牌时,我 select "manage_pages"、publish_pages" & "publish_actions" 权限。如果使用 Graph Explorer 执行使用密钥获取对 https://graph.facebook.com/v2.3/debug_token 的请求我获得了我 select 编辑的三个权限,外加一个 "public_profile" 权限,一切似乎都很好。

当我 运行 在我的应用程序和 C# 代码中 运行 向 https://graph.facebook.com/v2.3/debug_token 发送一个 GET 请求时,使用我查询时使用的相同访问令牌,但是使用应用程序自己的访问权限它在 运行 时生成的密钥进行身份验证,我获得的唯一权限是 "public_profile",即使对 https://graph.facebook.com/v2.3/" + PageID + "/?fields=can_post returns 的 GET 请求可以使用访问密钥对于 posting,但是当我尝试 post 时,我得到一个错误,即我缺少我首先 selected 的 3 个关键权限。

发生了什么事?

作为参考,以下是我正在使用的功能;

//THIS IS THE FUNCTION USED TO CHECK IF THE TOKEN IS VALID
static bool checkValidToken(string inputToken)
{
    string url = "https://graph.facebook.com/v2.3/debug_token?input_token=" + inputToken + "&access_token=" + getAppAccessToken();
    WebRequest wrGETURL = WebRequest.Create(url);
    Stream objStream = wrGETURL.GetResponse().GetResponseStream();
    StreamReader objReader = new StreamReader(objStream);

    string jsonResponse = objReader.ReadToEnd();
    JObject resonse = (JObject)JObject.Parse(jsonResponse).GetValue("data");
    return (bool)resonse.GetValue("is_valid");
}
//THIS IS USED TO CHECK IF THE TOKEN CAN BE USED TO POST TO PAGE
static bool checkCanPost(string inputToken)
{
    WebRequest wrGETURL = WebRequest.Create("https://graph.facebook.com/v2.3/" + PageID + "/?fields=can_post&access_token=" + inputToken);
    Stream objStream = wrGETURL.GetResponse().GetResponseStream();
    StreamReader objReader = new StreamReader(objStream);

    string jsonResponse = objReader.ReadToEnd();
    JObject resonse = (JObject)JObject.Parse(jsonResponse);
    return (bool)resonse.GetValue("can_post");
}
//USED TO CALCULATE THE EXPIRY DATE ON THE TOKEN
static DateTime getExpiryDate(string inputToken)
{

    WebRequest wrGETURL = WebRequest.Create("https://graph.facebook.com/v2.3/debug_token?input_token=" + inputToken + "&access_token=" + getAppAccessToken());
    Stream objStream = wrGETURL.GetResponse().GetResponseStream();
    StreamReader objReader = new StreamReader(objStream);

    string jsonResponse = objReader.ReadToEnd();
    JObject resonse = (JObject)JObject.Parse(jsonResponse).GetValue("data");
    DateTime expires = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Local).AddSeconds((int)resonse.GetValue("expires_at"));
    if ((int)resonse.GetValue("expires_at") == 0)
    {
        expires = DateTime.UtcNow.AddMonths(2);
    }
    return expires;
}
//USED TO GENERATE THE APP ACCESS TOKEN
static string getAppAccessToken()
{
    WebRequest wrGETURL = WebRequest.Create("https://graph.facebook.com/v2.3/oauth/access_token?client_id=" + AppID + "&client_secret=" + AppSecret + "&grant_type=client_credentials");

    Stream objStream = wrGETURL.GetResponse().GetResponseStream();
    StreamReader objReader = new StreamReader(objStream);


    string jsonResponse = objReader.ReadToEnd();
    JObject resonse = JObject.Parse(jsonResponse);

    return (string)resonse.GetValue("access_token");
}
//USED TO EXTEND AN EXISTING TOKEN
static string extendToken(string inputToken)
{
    WebRequest wrGETURL = WebRequest.Create("https://graph.facebook.com/v2.3/oauth/access_token?grant_type=fb_exchange_token&client_id=" + AppID + "&client_secret=" + AppSecret + "&fb_exchange_token=" + inputToken);

    Stream objStream = wrGETURL.GetResponse().GetResponseStream();
    StreamReader objReader = new StreamReader(objStream);


    string jsonResponse = objReader.ReadToEnd();
    JObject resonse = JObject.Parse(jsonResponse);
    Console.WriteLine(jsonResponse);
    return (string)resonse.GetValue("access_token");
}
//USED TO GENERATE A TOKEN FOR POSTING AS THE PAGE, RATHER THAN TO THE PAGE
static string getPageToken(string inputToken)
{
    WebRequest wrGETURL = WebRequest.Create("https://graph.facebook.com/v2.3/"+PageID+"?fields=access_token&access_token="+inputToken);

    Stream objStream = wrGETURL.GetResponse().GetResponseStream();
    StreamReader objReader = new StreamReader(objStream);


    string jsonResponse = objReader.ReadToEnd();
    JObject resonse = JObject.Parse(jsonResponse);

    return (string)resonse.GetValue("access_token");
}
//FUNCTION FOR GETTING ALL PERMISSIONS FOR A TOKEN
static List<string> getTokenPermissions(string inputToken)
{
    string url = "https://graph.facebook.com/v2.3/debug_token?input_token=" + inputToken + "&access_token=" + getAppAccessToken();
    WebRequest wrGETURL = WebRequest.Create(url);
    Stream objStream = wrGETURL.GetResponse().GetResponseStream();
    StreamReader objReader = new StreamReader(objStream);

    string jsonResponse = objReader.ReadToEnd();
    JObject resonse = (JObject)JObject.Parse(jsonResponse).GetValue("data");
    JToken scopes = resonse.GetValue("scopes");

    List<string> returnList = new List<string>();
    foreach (JToken tokrow in scopes)
    {
        returnList.Add((string)tokrow);
    }
    return returnList;
}
//DEBUG FUNCTION FOR OUTPUTTING ALL OF A TOKENS USER/PAGE PERMISSIONS
static void outputPermissions(string theToken)
{
    List<string> userPermissions = getTokenPermissions(theToken);
    List<string> appPermissions = getTokenPermissions(getPageToken(theToken));
    Console.WriteLine("USER:");
    foreach (string perm in userPermissions)
    {
        Console.WriteLine(perm);
    }
    Console.WriteLine("APP:");
    foreach (string perm in appPermissions)
    {
        Console.WriteLine(perm);
    }
    Console.Read();
}
// FUNCTION THAT ACTUALLY POSTS TO THE PAGE
static async Task PostHandler(Post toPost,string theToken)
{
    using (var client = new HttpClient())
    {
        var values = new Dictionary<string, string>
                {
                   { "url", toPost.ImageURL },
                   {"access_token",getPageToken(theToken)},
                   {"caption",toPost.Caption}
                };
        Console.WriteLine("Image we are uploading is " + toPost.ImageURL);
        var content = new FormUrlEncodedContent(values);

        var response = await client.PostAsync("https://graph.facebook.com/v2.3/" + PageID + "/photos", content);
        Console.WriteLine("Uploaded!");
        var responseString = await response.Content.ReadAsStringAsync();
        Console.WriteLine(responseString);
        Console.Read();
        JObject resonse = JObject.Parse(responseString);
    }
}

当 post 运行 它 returns

error #200 Requires extended permission: (manage_pages and pubish_pages) or (manage_pages and publish_actions)

问题中的错误实际上是 Facebook 团队引入的错误,不幸的是恰好与我的应用程序测试同时发生,因为发布错误已被记录并更正。

可以在 developers.facebook.com/bugs/380833342117530

找到更多信息