Domanda

Ho il seguente script che funziona, cioè si va alla pagina di Facebook Login se l'utente non è già connesso, e chiede loro se sono ok con l'applicazione per inviare messaggi sulla sua bacheca:

<?php
    require 'facebook.php';

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

    $session = $facebook->getSession();

    if ($session) {

        if (isset($_GET[id])) {

            $post = $facebook->api("/" . $_GET['id'] . "/feed", "POST",  array('message' => 'Hello!'));
            echo 'A message has been posted on your friends wall';

        } else {

            $friends = $facebook->api('/me/friends');

            foreach ($friends as $key=>$value) {
                echo 'You have ' . count($value) . ' friends<br />';

                foreach ($value as $fkey=>$fvalue) {
                    echo 'friend id = ' . $fvalue[id] . ' - friend name = ' . $fvalue[name] . ' - <a href="/stage2.php?id=' . $fvalue[id] . '">post message</a><br />';
                }
            }
        }

    } else {

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

        header('Location: '.$loginUrl);
    }
?>

Come può essere migliorata in modo che non richiede autorizzazioni estese in partenza. Deve solo chiedere permessi di base per visualizzare la lista amici, e solo chiedere autorizzazioni estese, se l'utente fa clic sul amico Per inviare un messaggio.

È stato utile?

Soluzione

in fretta, c'è qualcosa che voglio sottolineare per quanto riguarda il seguente blocco di codice:

foreach ($friends as $key=>$value) {
    echo 'You have ' . count($value) . ' friends<br />';

    foreach ($value as $fkey=>$fvalue) {
        echo 'friend id = ' . $fvalue[id] . ' - friend name = ' . $fvalue[name] . ' - <a href="/stage2.php?id=' . $fvalue[id] . '">post message</a><br />';
    }
}

Il primo ciclo foreach è davvero fuorviante e non le buone pratiche a tutti. L'API grafico non è eccessivamente consistente nel modo in cui presenta i dati, ma la ragione si sta facendo la foreach è quello di affrontare con la chiave data in oggetto JSON che viene restituito. Questo è generalmente una cattiva idea, perché tale chiave data è tipicamente presente insieme ad altri tasti (come paging). Invece, voglio verificare che $friends['data'] non è vuota, e poi ri-assegnare la matrice $friends questo modo:. $friends = $friends['data'];

Esempio:

if (!empty($friends['data']))
{
    $friends = $friends['data'];
}
else
{
    $friends = array();
}

Ora, per la tua domanda.

È detto che non si vuole a un eccesso di chiedere permessi. Questa è una grande cosa da desiderare, ma il problema con esso è che Facebook non lo rende estremamente facile da controllare per le autorizzazioni che non hanno o non hanno. C'è un tavolo FQL che permette di controllare se l'utente ha un certo insieme di permessi, ma questa tabella non viene aggiornato con qualsiasi tipo di urgenza. Se si ottengono i permessi in più da un utente (o se un utente si ritrae autorizzazioni) e poi controllare questa tabella FQL per lo stato del permesso, si può (e probabilmente sarà) leggere il valore errato e si otterrà un falso positivo.

Sono disponibili tre opzioni per affrontare questo, che mi viene in mente proprio fuori dalla parte superiore della mia testa.

  1. Continua sul vostro codice stage1.php, come sei - non c'è niente di sbagliato nel modo in cui si sta ottenendo l'installazione e la sessione per l'utente lì. Si cambia pagina 2 per reindirizzare l'utente attraverso l'endpoint OAuth che richiede il permesso di pubblicare-stream ogni volta che l'utente carica la pagina. L'endpoint OAuth non verrà più richiesto all'utente di installare, e li invierà sulla loro strada.

    Gli svantaggi di questo approccio è, ogni richiesta di inviare a turno muro Un'amici in 3 richieste.

    • Il caricamento iniziale della pagina
    • L'OAuth redirect / carico
    • Il reindirizzamento da OAuth di nuovo alla vostra applicazione

    Questo approccio richiede anche che si aggiunge una bandiera per la vostra chiave next nel vostro loginUrl, che si può cercare di assicurarsi che l'utente ha attraversato l'endpoint OAuth, altrimenti si sta andando ad ottenere un errore di reindirizzamento infinito.

  2. Utilizzare la FB Javascript SDK per verificare la presenza di corrente dei vostri utenti set di autorizzazioni. Per fare questo, si utilizzano il href="http://developers.facebook.com/docs/reference/javascript/FB.getSession/" rel="nofollow"> FB.getLoginStatus metodo

    Esempio:

    <div id="fb-root"></div>
    <script src="http://code.jquery.com/jquery-1.5.2.min.js"
        type="text/javascript" charset="utf-8">
     </script>
    <script src="http://connect.facebook.net/en_US/all.js"
        type="text/javascript" charset="utf-8">
     </script>
    <script type="text/javascript">
    (function($)
    {
        FB.init({
            appId: '<?= FB_APP_ID; ?>',
            cookie: true,
            status: true,
            xfbml: true
        });
    
        $('a').click(function(event)
        {
            var self = this;
    
            event.preventDefault();
    
            FB.getLoginStatus(function(session)
            {
                if (session.perms.match(/\"publish_stream\"/))
                {
                    /* This user has publish stream, so we don't need
                     * to ask again
                    **/
                    window.location = $(self).attr('href');
                }
                else
                {
                    /* This user does not have publish stream, so we need
                     * to ask.
                    **/
                    FB.login(function(response)
                    {
                        if (response && response.perms.match(/publish_stream/))
                        {
                            /* We now have publish stream access! */
                            window.location = $(self).attr('href');
                        }
                    }, {
                        perms: 'publish_stream'
                    });
                }
            })
    
            return false;
        })
    })(jQuery);
    
  3. non utilizzano alcun autorizzazioni estese, utilizzare il Javascript SDK (di nuovo) e dare all'utente un publish-finestra per ogni utente che vorrebbero pubblicare sul muro della. Questa è una cosa relativamente facile da fare, anche.

    Esempio:

    Dato il tuo link per gli utenti:

    <a href="#" data-id="123">Friend 1</a>
    <a href="#" data-id="456">Friend 2</a>
    <a href="#" data-id="789">Friend 3</a>
    

    Si può fare qualcosa di simile:

    <div id="fb-root"></div>
    <script src="http://code.jquery.com/jquery-1.5.2.min.js"
        type="text/javascript" charset="utf-8">
    </script>
    <script src="http://connect.facebook.net/en_US/all.js"
        type="text/javascript" charset="utf-8">
    </script>
    <script type="text/javascript">
    (function($)
    {
        $('a').click(function(event)
        {
            var user_id = $(this).data('id');
    
            FB.ui({
                method:    'feed',
                message:   'Hello!',
                to:         user_id
            }, function(response)
            {
                //this gets called whether it was successful, or not.
            })
        });
    
    })(jQuery);
    

Altri suggerimenti

Ecco una riscrittura del codice, con quello che che sono le migliori pratiche:

<?php
require 'facebook.php';

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

$session = $facebook->getSession();
// Prepare the login url with the right permission
$loginUrl = $facebook->getLoginUrl(array(
    'req_perms' => 'publish_stream',
    'next' => 'http://'.$_SERVER['SERVER_NAME'].'/stage1.php',
    'cancel_url' => 'http://'.$_SERVER['SERVER_NAME'].'/cancel.php',
));

if ($session) {
    try {
        // Before processing the request
        // check if we got the right permission
        $perms = $facebook->api(array(
            "method"    => "fql.query",
            "query"     => "SELECT publish_stream FROM permissions WHERE uid=me()"
        ));
        if($perms[0]['publish_stream']==='1') {
            // We have the right permission
            if (isset($_GET['id'])) {
                // A small security measure
                $id = (int) $_GET['id'];
                $post = $facebook->api("/$id/feed", "POST",  array('message' => 'Hello!'));
                echo 'A message has been posted on your friends wall';
            } else {
                $friends = $facebook->api(array(
                    "method"    => "fql.query",
                    "query"     => "SELECT uid,name FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=me())"
                ));
                foreach($friends as $friend)
                    echo "friend id = {$friend['uid']} - friend name = {$friend['name']} - <a href=\"/stage2.php?id={$friend['uid']}\">post message</a><br />";
            }
        } else {
            // We don't have the right permission
            header('Location: '.$loginUrl);
        }
    } catch (FacebookApiException $e) {
        error_log($e);
    }
} else {
    header('Location: '.$loginUrl);
}
?>

Come verificare la presenza di un permesso è spiegata qui . Anche io ho commenti per salvare la scrittura una spiegazione aggiunto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top