Facebook přihlašování v PHP

U webových aplikací, kde potřebujeme od uživatele jeho přihlášení, můžeme místo klasické zdlouhavé registrace využít přihlášení pomocí jiné autority, kde je uživatel již zaregistrovaný. Jednou z možností je přihlášení pomocí sociální sítě Facebook, kde je registrovaná většina uživatelů Internetu. Vždy bychom měli ale poskytnou i klasickou možnost registrace.

Jak to funguje z pohledu uživatele

Na svých stránkách zobrazíme tlačítko "Přihlásit se pomocí Facebooku", které po kliknutí přesměruje uživatele na stránky Facebooku, kde se mu zobrazí potvrzovací dialog. Pro zobrazení tohoto dialogu je potřeba, aby byl uživatel na Facebooku přihlášen.

Uživatel v dialogu přímo vidí, která aplikace tuto akci vyvolala a jaké informace o nás chce získat. V základním nastavení se posílá jméno, profilový obrázek, uživatelské ID, seznam přátel a data, která uživatel publikuje veřejně. E-mail, který budeme pravděpodobně potřebovat, se neposílá. Po odsouhlasení dialogu je uživatel vrácen zpět na stránky, kde je již přihlášen. Celý proces je tedy ideálně na dvě kliknutí a uživatel si nemusí vytvářet žádný účet.

Implementace v PHP

Pro implementaci v jazyku PHP využijeme přímo SDK poskytované od Facebooku, které je umístěno na GitHubu: Facebook PHP SDK. SDK nám zajistí pohodlný přístup k celému Facebook Graph API. Přihlašování je tak jedna z možných funkcí, které API poskytuje. Více informací lze najít v oficiální dokumentaci SDK for PHP.

Registrace aplikace

Ještě než se pustíme do vlastní implementace, je potřeba zaregistrvat naší webovou stránku jako Facebook App. To provedeme na stránce Facebook Developers, pomocí tlačítka Create New App. Název zvolíme např. doménu stránek a  vyplníme App Domains, čímž říkáme z jakých URL lze přihlašování použít. Níže pak zvolíme "Website with Facebook Login" a opět vyplníme URL našich stránek.

Nejdůležitější informace jsou pro nás App ID a App Secret, které budeme vyžadovat při následné implementaci.

Nastavení aplikace

Pro mojí implementaci potřebuji hlavně uživatelský e-mail, který se ale v základním nastavení přihlašování naposílá. V levém menu tedy zvolím položku Permissions, kde v políčku User & Friend Permission nastavím políčko "e-mail". Lze nastavit i další informace, které Facebook zašle, ale musíme počítat s tím, že uživatel o tom bude informován v potvrzovacím dialogu a čím více informací budeme po něm chtít, tím menší je šance, že nám přihlášení potvrdí. Neměli bychom vyžadovat více informací, než opravdu potřebujeme.

V záložce Settings/Advenced pak můžeme vyplnit URL naší adresy, která bude zavolána pokud se uživatel z Facebooku odhlásí. Vhodné je také nahrát logo aplikace, aby se zvýšila důveryhodnost přihlášení. To provedeme v záložce App Details dole, kde lze nahrát i více velikostí loga.

Implementace v PHP

Použijeme výše zmíněné PHP SDK, které zkopírujeme do naší aplikace. Pohledem na ukázková přihlášení vidíme, že je potřeba vytvořit třídu Facebook() kde jako parametr posíláme App ID a App Secret.

Toto volání budeme mít ale na více místech, vytvořím si proto novou třídu MyFacebook(), kde si přístupové údaje uložím jako konstanty a nemusíme se o to starat:

<?php
require_once './lib/Facebook/facebook.php';
class MyFacebook extends Facebook {
    const APP_ID = '123';
    const APP_SECRET = 'abc';
    public function __construct() {
        $options = array(
            'appId' => self::APP_ID,
            'secret' => self::APP_SECRET,
        );
        parent::__construct($options);
    }
}

Nyní můžeme jednoduše volat:

$facebook = new MyFacebook();

Přihlašování pak uděláme dle návodu na GitHubu, který musíme upravit. Jedná se o naivní implementaci, která se bude výrazně lišit podle aplikace, kde přihlašování nasazujeme. V kódu níže např. řeším vytvoření uživatelského účtu, pokud předtím neexistoval.

// init
$facebook = new MyFacebook();
$usersDao = new UsersRepository();
$url = "";
$user = $facebook->getUser();

// zkusime jestli je prihlaseny
if ($user) {
  try {
    $user_profile = $facebook->api('/me');
  } catch (FacebookApiException $e) {
    error_log($e);
    $user = null;
  }
}

// pokud je prihlaseny na Fb a neprihlasen v nasi app
if ( $user AND empty($_SESSION["logged"]) ) {

    // zkontrolujeme jestli jsme dostali email
    if ( !empty( $user_profile["email"]) ) {
        // musime ho prihlasit, nebo vytvorit ucet
        $email = $user_profile["email"];
        if ( !$usersDao->isUserExist($email) ) {
            $usersDao->addUser($email);
        }
        $user = $usersDao->getUser($email);
        if ( $user) {
            $_SESSION["logged"] = $user["email"];
            header("Location: /");
            exit;
        }
    }

// pokud jsme neziskali email
} else {
    $params = array(
        'scope' => 'email'
    );
    // vygenerujeme prihlasovaci URL
    $url = $facebook->getLoginUrl($params);
}
$this->template->facebook_url = $url;

Tímto máme vyřešené přihlášení uživatele do naší aplikace.

Odhlášení z aplikace

Odhlášení bude už jednodušší, postačí pár řádek pro zrušení session:

$facebook = new MyFacebook();
$facebook->destroySession();
unset($_SESSION["logged"]);

Na tento skript rovněž nastavíme Deauthorise Callback URL z nastavení Facebook aplikace.

Zobrazení profilového obrázku

URL obrázku získáme z proměnné $user_profile v přihlašovacím skriptu, případně kdekoliv v aplikaci zavoláním:

$facebook = new MyFacebook();
$user = $facebook->getUser();
if ($user) {
    $user_profile = $facebook->api('/me');
}