Aplikace pro Facebook, díl II. – autorizace

V druhém díle seriálu o tvoření aplikací pro dnes nejpopulárnější sociální síť – Facebook – si představíme princip autorizace aplikace, podíváme se na protokol OAuth, který ověřuje přístupová práva ke Graph API, a nakonec si vše názorně předvedeme na ukázce.

Seriál: Napište si s námi aplikaci pro Facebook (2 díly)

  1. Aplikace pro Facebook od základů – díl I. 7.9.2011
  2. Aplikace pro Facebook, díl II. – autorizace 3.10.2011

minulém díle našeho seriálu jsme vytvořili „Hello world“ aplikaci v PHP za použití oficiální Facebook knihovny. Řekli jsme si, že aplikace na Facebooku jsou „obyčejné“ webové stránky, běžící na vašem serveru, a do Facebooku vložené IFRAMEm.

Dnes se podíváme na:

  • Princip autorizace (získání extended_permis­sions) pro aplikaci
  • Princip protokolu OAuth použitého pro přístup ke Graph API
  • Ukázku autorizace pomocí PHP (server-side) a JavaScriptu (client-side)

Autorizace aplikace na Facebooku

Většina dat dostupných přes Graph API není veřejná. V praxi to znamená, že po spuštění aplikace u uživatele (je jedno, jestli v záložce nebo jako standardní aplikace) je potřeba aplikaci autorizovat a získat tak klíč (tzv. access_token) s vámi definovanými možnostmi (extended_per­missions – seznam práv, která vyžadujete po uživateli).

Do extended_permis­sions spadá např.:

  • posílání wallpostů
  • nahrávání fotek
  • likování komentářů
  • správa stránek apod.

Access_token má ve výchozím stavu omezenou časovou platnost, po které je potřeba získat klíč nový. Při získávání nového tokenu u již autorizované aplikace se Facebook na udělení extended_permis­sions uživatele neptá a klíč rovnou poskytne.

Speciálním případem je tzv. Offline access (jedno z extended_per­missions), který umožní získat access_token s neomezenou platností (a to i pro případ, kdy se uživatel odhlásí z Facebooku). Offline access se však spíše hodí pro webové služby s Facebook Connectem nebo na speciality s použitím CRONu, na běžné aplikace nám postačí access_token bez Offline accessu.

Protokol OAuth2

Facebook používá pro zabezpečení Graph API standardní OAuth protokol ve verzi 2. Nebudeme se zde pouštět do podrobností, o samotném protokolu si můžete přečíst článek zde na Zdrojáku.

OAuth na Facebooku ve zkratce

  1. Vytvoříme autorizační URL, která vede k zobrazení OAuth dialogu. Autorizační URL obsahuje ID aplikace, extended_permis­sions a redirect_uri – adresu, na kterou je uživatel následně zpět přesměrován.
  2. Pokud uživatel povolí přístup aplikace v dialogu, je přesměrován na redirect_uri s autorizačním kódem v GET parametru
  3. Kombinací autorizačního kódu a App_secret (tajný klíč aplikace dostupný ve vývojářské aplikaci, který s nikým nesdílejte) získáte nakonec access_token.
  4. S access_tokenem už můžete vesele posílat požadavky na API.

Pozn.: Pokud vyprší platnost access_tokenu, je při získávání nového přeskočen krok se zobrazením dialogu (tzn. že uživatel je okamžitě přesměrován na redirect_uri).

PHP autorizace

V aplikaci vycházíme z kódu předchozího dílu.

Budeme pracovat s námi vytvořenou session přihlášeného uživatele a podle potřeby přesměrujeme uživatele na OAuth dialog:

define('EXTENDED_PERSMISSIONS', 'publish_stream');

// Uživatel není přihlášen || Neautorizoval aplikaci
if (!isset($_SESSION["user_logged"])) {
    $redirect_uri = CANVAS_PAGE . "?foo=bar";
    echo("<script> top.location.href='" . $facebook->getLoginUrl(array("scope" => EXTENDED_PERSMISSIONS, "redirect_uri" => $redirect_uri)) . "'</script>");
}

Pokud se uživatel vrátí zpět na redirect_uri, získáme autorizační token (ten použijeme pro získání access_tokenu):

            // Uživatel povolil autorizaci a vrací se na redirect_uri
if (isset($_REQUEST["code"])) {
    $_SESSION["user_logged"] = TRUE;

    // Zbavíme se "?code" z URL
    echo("<script> top.location.href='" . CANVAS_PAGE . "'</script>");
}

Jestliže uživatel autorizaci zamítne (nebo se autorizace z nějakého důvodu nepovede), dozvíme se o tom následovně:

// Uživatel nepovolil autorizaci aplikace
    if (isset($_REQUEST['error'])) {
    die("Uzivatel zamitnul autorizaci aplikace!");
    }

Wallpost

Nyní, když máme autorizovanou aplikaci<a>* a publish_stream práva, můžeme se pustit do samotného wallpostu.

Poznámka:

*) V této aplikaci uložení access_tokenu necháváme na knihovně. Není však problém získat a uložit access_token manuálně a mít tedy i tuto část plně pod kontrolou. Po obdržení autorizačního kódu od uživatele získáte access_token např. přes file_get_contents() z: 

https://graph.facebook.com/oauth/access_token?
     client_id=APP_ID&redirect_uri=REDIRECT_URI&
     client_secret=APP_SECRET&code=AUTORIZACNI_KOD

Graph API předáme wallpost jako klasické pole:

$wall_post_attachment = array(
          'message' => 'Testovací wallpost z mojí aplikace',
          'name' => 'Zdroják.cz',
          'caption' => "Tvorba webových stránek a aplikací",
          'link' => 'https://www.zdrojak.cz',
          'description' => 'Denní zpravodajství pro webové vývojáře, kodéry...',
          'picture' => 'http://i.iinfo.cz/z/logo-zd.gif');

Komunikaci s API zajišťuje metoda api().

    try {
    // Odešleme Wallpost pomocí Graph API na Facebook
    $result = $facebook->api('/me/feed/', 'post', $wall_post_attachment);
    } catch (FacebookApiException $e) {
    echo "Chyba: " . $e->getMessage();
    }

První parametr metody api jsou data, s kterými pracujeme a uživatelské id (v tomto speciálním případě označuje „me“ aktuálně přihlášeného uživatele). Dostupné jsou např.:

  • me/likes
  • me/movies
  • me/notest atd.

Druhý parametr specifikuje, zda data přijímáme nebo odesíláme (POST || GET). A poslední parametr je samotný Wallpost.

Celou aplikaci si můžete stáhnout zde.

Autorizace pomocí JavaScript SDK

Autorizace pomocí JS SDK je poměrně jednoduchá. Ve srovnání s autorizací na straně serveru se hodí lépe pro webové stránky propojené s Facebookem (např. pokud chcete na své službě umožnit uživateli přihlášení pomocí Facebooku). Nehodí se pro stránky a aplikace, které jsou funkčně závislé na Facebooku již při startu, a to především proto, že autorizační dialog nelze zobrazit při načtení stránky, protože ho prohlížeč s největší pravděpodobností zablokuje (automaticky vyskakující pop-up). Je tedy třeba autorizaci volat např. na onclick událost tlačítka. Níže je ukázka zdrojového kódu, který umožní pomocí tlačítek autorizovat (přihlásit se k) aplikaci, odhlásit se z aplikace a aplikaci deautorizovat (odebrat jí práva). V příkladu je použita jQuery. Podrobné vysvětlení je k nalezení přímo v kódu:

index.html

<!DOCTYPE html>
<html lang="cs-cz" dir="ltr">
<head>
<meta charset="UTF-8">
<title>JS AUTH zdroják</title>

<!-- jQuery - www.jquery.com -->
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
</head>
<body>

<!-- Na tento div nezapomeňte, Facebook si do něj natahá svá data -->
<div id="fb-root">
</div>

<!-- Vzdáleně includujeme JS SDK  -->
<script type="text/javascript" src="http://connect.facebook.net/cs_CZ/all.js"></script>

<!-- soubor s našimi funkcemi (obsah níže) -->
<script type="text/javascript" src="./fbfunctions.js"></script>


<script type="text/javascript">
//inicializujeme knihovnu, všimněte si, že narozdíl od PHP SDK není třeba secret key
FB.init({
    appId : 114242578683200,
    status : true,
    cookie : true,
    xfbml : true,
    oauth: true
});

//Zjistí zda existuje session uživatele a vykoná funkci handleSessionResponse  (callback)
FB.getLoginStatus(handleSessionResponse);

</script>

<!-- Uživatele požádá o přihlášení a pokud není autorizován i o autorizaci -->
<button id="login" onclick="login()">Login</button>

<!-- Uživatele odhlásí z aplikace -->
<button id="logout" onclick="logout()">Logout</button>

<!-- Uživatele odhlásí z aplikace a odebere autorizaci -->
<button id="disconnect" onclick="disconnect()">Disconnect</button>

<!-- Sem vložíme obsah dle stavu uživatele -->
<div id="content">
</div>

</body>
</html>

fbfunctions.js

/* Přihlášení / autorizace uživatele. V případě, že autorizace ještě neproběhla, je uživateli zobrazen autorizační dialog, jinak je pouze vytvořena session a uživatel nic nepozoruje    */
function login(){
    FB.login(handleSessionResponse, {
        scope: 'publish_stream' // jednotlivá práva oddělujeme čárkami bez mezery
    });
}

/* Odhlášení uživatele z aplikace */
function logout() {
   FB.logout(handleSessionResponse);
}

 /* Odhlášení a odebrání autorizace uživatele */
function disconnect() {
               if (response.authResponse) {
          FB.api('/me/permissions', 'delete', function(response) {
                  $('#content').html('<p>Uživatel odhlášen a práva odebrána</p>');
             });
           }
    
}

/*callback, zjistí zda byla vytvořena session a dle toho zobrazí požadovaný obsah */
function handleSessionResponse(response){
        var res = response.authResponse;
    if (!res) { //pokud nemáme platnou session uživatele
        $('#content').html('<p>Uživatel není přihlášen</p>');
    }
    else { //pokud máme session uživatele a uživatel tedy je přihlášený
                   
        FB.api(
          {
            method: 'fql.query',
            query: 'SELECT name, pic FROM profile WHERE id=' + res.userID //res obsahuje např i access_token, který můžeme využít pro získání neveřejných dat
            
          },
          function(response) {
            var user = response[0];
            $('#content').html('<img src="' + user.pic + '">' + user.name);
          
          }
        );
    }
    
   
}

Závěr

V dnešním díle jsme si ukázali tu nejdůležitější část pro tvorbu aplikací na Facebooku. S tímto základem jsme schopni do své aplikace implementovat veškerou dostupnou funkcionalitu Facebooku.

V dalším díle se zaměříme na novinky představené na nedávné konferenci F8 (kdy, kde). Konkrétně se bude jednat o:

  • Activities v Graph API
  • Timeline API
  • Notifications

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 13

Přehled komentářů

facebok zbytečnost facebok zbytečnost
Ty jsi ale jeliman Re: facebok zbytečnost
Michal Re: facebok zbytečnost
Láďa OAuth 2.0
Václav Dohnal Re: OAuth 2.0
Láďa Re: OAuth 2.0
Michal Májský Re: OAuth 2.0
Michal Májský Re: OAuth 2.0
Jan Prachař Re: OAuth 2.0
Michal Májský Re: OAuth 2.0
cimenta Jak automaticky ukladat "updates" mych pratel?
Michal Májský Re: Jak automaticky ukladat "updates" mych pratel?
shneck Už jsem zoufalý
Zdroj: https://www.zdrojak.cz/?p=3552