【问题标题】:facebook extended permissions脸书扩展权限
【发布时间】:2011-04-26 18:46:28
【问题描述】:

更新 2:

好的,通过改变让它“有点”工作:

$loginUrl = $facebook->getLoginUrl(array(
           'canvas' => 1,
           'fbconnect' => 0,
           'req_perms' => 'publish_stream',
           'next' => 'http://'.$_SERVER['SERVER_NAME'].'/success.php',
           'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php'
        ));

到这里:

$loginUrl = $facebook->getLoginUrl(array(
           'canvas' => 1,
           'fbconnect' => 0,
           'req_perms' => 'publish_stream',
           'next' => 'http://'.$_SERVER['SERVER_NAME'].'/success.php',
           'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php'
        ));
        header('Location: '.$loginUrl);

即我添加了header('Location: '.$loginUrl);

但是页面的行为很奇怪。我必须导航到页面,登录,然后刷新页面,再次登录,然后它会询问我是否允许发布到该页面,最终它会发布到该页面。

为什么我必须登录两次?

更新 1:

我现在有以下脚本,它似乎不起作用。在这种状态下,我只是想在自己的墙上发帖,但最终也会想在朋友的墙上发帖:

<?php
    /**
     *
     * Copyright 2011 Facebook, Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License"); you may
     * not use this file except in compliance with the License. You may obtain
     * a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     * License for the specific language governing permissions and limitations
     * under the License.
     */


    require 'facebook.php';

    // Create our Application instance (replace this with your appId and secret).
    $facebook = new Facebook(array(
        'appId'  => '<appId removed for security reasons>',
        'secret' => '<secret removed for security reasons>',
        'cookie' => true,
    ));

    // We may or may not have this data based on a $_GET or $_COOKIE based session.
    //
    // If we get a session here, it means we found a correctly signed session using
    // the Application Secret only Facebook and the Application know. We dont know
    // if it is still valid until we make an API call using the session. A session
    // can become invalid if it has already expired (should not be getting the
    // session back in this case) or if the user logged out of Facebook.
    $session = $facebook->getSession();

    $me = null;
    // Session based API call.
    if ($session) {
        try {
            $uid = $facebook->getUser();
            $me = $facebook->api('/me');

            $post = $facebook->api("/me/feed", "POST",  array('message' => 'Hello! I\'m using the FB Graph API!'));
        } catch (FacebookApiException $e) {
            error_log($e);
        }
    }

    // login or logout url will be needed depending on current user state.
    if ($me) {
        $logoutUrl = $facebook->getLogoutUrl();
    } else {
        $loginUrl = $facebook->getLoginUrl(array(
           'canvas' => 1,
           'fbconnect' => 0,
           'req_perms' => 'publish_stream',
           'next' => 'http://'.$_SERVER['SERVER_NAME'].'/success.php',
           'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php'
        ));
    }

?>

<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
    <head>
        <title>php-sdk</title>

        <style>
            body {
                font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
            }

            h1 a {
                text-decoration: none;
                color: #3b5998;
            }

            h1 a:hover {
                text-decoration: underline;
            }
        </style>
    </head>

    <body>
    <!--
        We use the JS SDK to provide a richer user experience. For more info,
        look here: http://github.com/facebook/connect-js
    -->
        <div id="fb-root"></div>
        <script>
        window.fbAsyncInit = function() {
            FB.init({
                appId   : '<?php echo $facebook->getAppId(); ?>',
                session : <?php echo json_encode($session); ?>, // don't refetch the session when PHP already has it
                status  : true, // check login status
                cookie  : true, // enable cookies to allow the server to access the session
                xfbml   : true // parse XFBML
            });

            // whenever the user logs in, we refresh the page
            FB.Event.subscribe('auth.login', function() {
                window.location.reload();
            });
        };

        (function() {
            var e = document.createElement('script');
            e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
            e.async = true;
            document.getElementById('fb-root').appendChild(e);
        }());
    </script>


    <h1><a href="example.php">php-sdk</a></h1>

    <?php if ($me): ?>
        <a href="<?php echo $logoutUrl; ?>">
            <img src="http://static.ak.fbcdn.net/rsrc.php/z2Y31/hash/cxrz4k7j.gif">
        </a>
    <?php else: ?>
        <div>
            Using JavaScript &amp; XFBML: <fb:login-button></fb:login-button>
        </div>
    <?php endif ?>

    <h3>Session</h3>
    <?php if ($me): ?>
        <pre><?php print_r($session); ?></pre>

        <h3>You</h3>
        <img src="https://graph.facebook.com/<?php echo $uid; ?>/picture">
        <?php echo $me['name']; ?>

        <h3>Your User Object</h3>
        <pre><?php print_r($me); ?></pre>
    <?php else: ?>
        <strong><em>You are not Connected.</em></strong>
    <?php endif ?>
  </body>
</html>

我收到以下错误:

[Wed Apr 27 22:28:16 2011] [error] [client <ip address removed for security reasons>] OAuthException: (#200) The user hasn't authorized the application to perform this action, referer: http://<ip address removed for security reasons>/index.php

原始问题:

我有以下工作脚本,允许某人使用他们的 facebook 详细信息登录我的页面,然后我可以捕获他们的 access_token 以便我可以将它与图形 api 一起使用:

<?php
    /**
     *
     * Copyright 2011 Facebook, Inc.
     *
     * Licensed under the Apache License, Version 2.0 (the "License"); you may
     * not use this file except in compliance with the License. You may obtain
     * a copy of the License at
     *
     *     http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing, software
     * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
     * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     * License for the specific language governing permissions and limitations
     * under the License.
     */


    require 'facebook.php';

    // Create our Application instance (replace this with your appId and secret).
    $facebook = new Facebook(array(
        'appId'  => 'app id goes here',
        'secret' => 'secret id goes here',
        'cookie' => true,
    ));

    // We may or may not have this data based on a $_GET or $_COOKIE based session.
    //
    // If we get a session here, it means we found a correctly signed session using
    // the Application Secret only Facebook and the Application know. We dont know
    // if it is still valid until we make an API call using the session. A session
    // can become invalid if it has already expired (should not be getting the
    // session back in this case) or if the user logged out of Facebook.
    $session = $facebook->getSession();

    $me = null;
    // Session based API call.
    if ($session) {
        try {
            $uid = $facebook->getUser();
            $me = $facebook->api('/me');
        } catch (FacebookApiException $e) {
            error_log($e);
        }
    }

    // login or logout url will be needed depending on current user state.
    if ($me) {
        $logoutUrl = $facebook->getLogoutUrl();
    } else {
        $loginUrl = $facebook->getLoginUrl();
    }

?>

<!doctype html>
<html xmlns:fb="http://www.facebook.com/2008/fbml">
    <head>
        <title>php-sdk</title>

        <style>
            body {
                font-family: 'Lucida Grande', Verdana, Arial, sans-serif;
            }

            h1 a {
                text-decoration: none;
                color: #3b5998;
            }

            h1 a:hover {
                text-decoration: underline;
            }
        </style>
    </head>

    <body>
    <!--
        We use the JS SDK to provide a richer user experience. For more info,
        look here: http://github.com/facebook/connect-js
    -->
        <div id="fb-root"></div>
        <script>
        window.fbAsyncInit = function() {
            FB.init({
                appId   : '<?php echo $facebook->getAppId(); ?>',
                session : <?php echo json_encode($session); ?>, // don't refetch the session when PHP already has it
                status  : true, // check login status
                cookie  : true, // enable cookies to allow the server to access the session
                xfbml   : true // parse XFBML
            });

            // whenever the user logs in, we refresh the page
            FB.Event.subscribe('auth.login', function() {
                window.location.reload();
            });
        };

        (function() {
            var e = document.createElement('script');
            e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
            e.async = true;
            document.getElementById('fb-root').appendChild(e);
        }());
    </script>


    <h1><a href="example.php">php-sdk</a></h1>

    <?php if ($me): ?>
        <a href="<?php echo $logoutUrl; ?>">
            <img src="http://static.ak.fbcdn.net/rsrc.php/z2Y31/hash/cxrz4k7j.gif">
        </a>
    <?php else: ?>
        <div>
            Using JavaScript &amp; XFBML: <fb:login-button></fb:login-button>
        </div>
    <?php endif ?>

    <h3>Session</h3>
    <?php if ($me): ?>
        <pre><?php print_r($session); ?></pre>

        <h3>You</h3>
        <img src="https://graph.facebook.com/<?php echo $uid; ?>/picture">
        <?php echo $me['name']; ?>

        <h3>Your User Object</h3>
        <pre><?php print_r($me); ?></pre>
    <?php else: ?>
        <strong><em>You are not Connected.</em></strong>
    <?php endif ?>
  </body>
</html>

用户登录后,我知道我可以通过以下方式获取他们的朋友列表:

https://graph.facebook.com/me/friends?access_token=...

我想不通的是如何使用扩展权限,所以我的应用可以发布到用户朋友的 Facebook 墙上。

显然我应该使用扩展权限以及以下内容:

curl -F 'access_token=...' \
     -F 'message=Hello, Arjun. I like this new API.' \
     https://graph.facebook.com/arjun/feed

我不明白我应该如何从 PHP 中做到这一点。

【问题讨论】:

标签: php facebook facebook-graph-api facebook-php-sdk facebook-authentication


【解决方案1】:

更新

好吧,我自己无法真正测试它,所以只是一些你可以尝试的建议。将$loginUrl 更改为:

$loginUrl = $facebook->getLoginUrl(array(
    'req_perms' => 'publish_stream',
    'next' => 'http://'.$_SERVER['SERVER_NAME'].'/success.php',
    'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php'
));

在整个上下文中,文件的顶部应如下所示:

require 'facebook.php';

$facebook = new Facebook(array(
    'appId' => '<appId removed for security reasons>',
    'secret' => '<secret removed for security reasons>',
    'cookie' => true,
));

$session = $facebook->getSession();

$me = null;
if ($session)
{
   try
   {
       $uid = $facebook->getUser();
       $me = $facebook->api('/me');

       $post = $facebook->api("/me/feed", "POST", array('message' => 'Hello! I\'m using the FB Graph API!'));
   }
   catch (FacebookApiException $e)
   {
      error_log($e);
   }
}
else
{
$loginUrl = $facebook->getLoginUrl(array(
        'req_perms' => 'publish_stream',
        'next' => 'http://' . $_SERVER['SERVER_NAME'] . '/success.php',
        'cancel_url' => 'http://' . $_SERVER['SERVER_NAME'] . '/cancel.php'
   ));
   header('Location: ' . $loginUrl);
}

好吧,首先检查你是否有会话,因此你需要配置Facebook SDK,如示例:

$facebook = new Facebook(array(
    'appId'  => 'app id goes here',
    'secret' => 'secret id goes here',
    'cookie' => true,
));

然后你可以检查用户是否登录,你的应用是否被授权:

if ($facebook->getSession() == null) {
   // not logged in or not authorized
}

if-clause 中,您必须重定向到正确的登录 URL 以获得您需要的所有权限:

$loginUrl = $facebook->getLoginUrl(array(
   'canvas' => 1,
   'fbconnect' => 0,
   'req_perms' => 'publish_stream',
   'next' => // url where to go when you were authorized
   'cancel_url' => // url to go to when user cancelled
));
header('Location: '.$loginUrl);

获得权限后,您可以按照文档中的说明使用发布

$facebook->api(/* url */, array(/* additional parameters go here */));

【讨论】:

  • 请参阅原始问题中的 UPDATE 1。我遇到了一个错误。
  • 请参阅原始问题中的 UPDATE 2。它工作正常,但不如预期。
  • 我不确定的一件事是,我有一个 facebook 登录按钮,要求用户登录,给我他们的身份验证 ID,如果我然后单击另一个按钮,它应该只要求允许在墙上发帖吗?但出于某种原因,它希望我再次登录。但我没有按钮来做到这一点。我将如何添加一个按钮来发布一个值。现在一切都在页面加载时发生。
【解决方案2】:

Facebook 的文档显示了完成此操作的原始实现,即您粘贴的 curl 调用。这基本上只是演示功能,并没有真正解释如何用您选择的语言完成任务。

正如迈克尔·罗斯在下面指出的那样,您首先需要申请在用户墙上发帖的扩展权限。为此,您的 $loginUrl 调用应该类似于:

$loginUrl = $facebook->getLoginUrl(array(
   'canvas' => 1,
   'fbconnect' => 0,
   'req_perms' => 'publish_stream',
   'next' => // url where to go when you were authorized
   'cancel_url' => // url to go to when user cancelled
));

这将提示用户安装您的应用程序并授予您对 publish_stream 扩展权限的访问权限,这是发布到他们的墙和他们朋友的墙所必需的。

为了真正制作墙贴,您的代码将类似于以下内容:

$facebook->api("/{$friends_fb_uid}/feed", "POST", 
    array('message' => 'Hello! I\'m using the FB Graph API!'));

在获得用户许可后,您应该在 POST 请求或对页面的某些请求(甚至是 ajax 请求)上使用它。 FB PHP SDK 应该会自动获取您用户的访问令牌,对其进行验证,然后为您发出请求。

【讨论】:

  • 所以基本上,我需要使用您提供的代码,通过页面上的按钮激活吗?
  • oshirowanen:提供的代码将在服务器端使用,因此在页面加载或 POST 请求时可能是有益的。因为您可能会询问用户他们想在谁的墙上发布,或者他们想发布什么消息(我怀疑您是否想将“我正在使用 fb graph api”发布到他们朋友的墙上)
  • @oshi 是的,该代码可用于在墙上发帖,您获得扩展权限之后。你必须明确地要求他们。
  • 正如 michael 指出的那样,您需要获得扩展权限才能发布到墙上。我在上面扩展了我的答案,向您展示了如何做到这一点。
  • 谢谢,我明天要试试这个。没有时间。感谢您的帮助。
【解决方案3】:

尝试改变

header('Location: '.$loginUrl);

echo '<script>top.location="'.$loginUrl.'";</script>';
die();

我不记得在哪里,但我在某处读到您必须使用 javascript 进行重定向。很久以前我读过它,所以它可能已经改变了。

【讨论】:

    猜你喜欢
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 2012-11-09
    • 2010-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多