Facebook API – Tutorial

Eins vorweg: Die Facebook API ist so mächtig, dass man locker auf der API basierend ein zweites Facebook hochziehen könnte, was durch die Facebook API gespeist wird. Leider gibt es aber auch zich verschiedene Quellen bei Facebook selbst. Vieles, was dort zu finden ist, ist bereits wieder deprecated und sollte nicht mehr verwendet werden. Ich werde nun sowohl die serverseitige (PHP) als auch die clientseitige (Javascript) Kommunikation mit Facebook anhand von Codeschnippseln beschreiben. Dabei verwende ich nur die Techniken, die laut Facebook noch verwendet werden sollten.

Getting Started

Als allererstes muss mal ein API Key her. Das geht hier. Dabei muss ein „App-Name“ vergeben werden und eine Domain spezifiziert werden. Wichtig: Nur Requests, die wirklich von der angegebenen Domain kommen, werden von Facebook zugelassen. Diese Domain kann allerdings jederzeit in eurem Developers-Account geändert werden und auch http://localhost/ geht durch. Dort kriegt ihr auch einen „secret-key“, der ebenfalls wichtig ist.

Serverseite

1) Facebook-Klasse und Zertifikat herunterladen

Auf der Github Seite die facebook.php und das Zertifikat herunterladen. Die Klasse werden wir für die API-Kommunikation brauchen und diese braucht wiederum das Zertikat. Achja, unbedingt CURL in der php.ini aktivieren!

2) Initialisierung

Der Konstruktor der Facebook-Klasse verlangt nach eurer App-ID und dem Secret-Key, den ihr beim Anmelden mitgeteilt bekommen habt.

$facebook = new Facebook(array(   'appId'  => 'eure-app-id',   'secret' => 'euer-secret-key',   'cookie' => true )); 

Jetzt kanns losgehen!

3) Login-Möglichkeit

Facebook Connect ist ein OAuth-Dienst, der es Benutzern ermöglicht, sich auf eurer Seite über Facebook einzuloggen. Diese melden sich dann mit ihrem Facebook Konto an und gewähren dadurch eurer Webseite Zugriff auf gewisse Daten ihres Profils. Das geht wie folgt:

$url = $facebook->getLoginUrl(array( 	'req_perms' => 'email,user_birthday,status_update,user_photos,user_videos,publish_stream', 	'next' => 'https://d-mueller.de/thanks.php', 	'cancel_url' => 'https://d-mueller.de/sorry.php'  ));  print '<a href="'.$url.'">Login!</a>'; 

Ein Klick auf den Login-Link leitet den Benutzer zu facebook weiter, wo er eurer App die Befugnis erteilen kann, seine E-Mail, seinen Geburtstag, seine Statusupdates und seine Fotos / Videos einzusehen. Weiterhin fordern wir noch das Privileg, auch Posts auf die Pinnwand des Nutzers schreiben zu dürfen. Das ist natürlich für ein simples Login völlig übertrieben und verschreckt Benutzer eher. Werden keine req_perms angegeben, ist Zugriff auf die öffentlichen Angaben des Users gestattet. Ist ja eigentlich auch ausreichend. Facebook sagt dazu

By default, your application can access all public data in a user’s profile, including her name, profile picture, gender, and friends

Zur next-URL wird weitergeleitet, nachdem der Benutzer akzeptiert hat. Zur cancel_url, wenn er verweigert hat. Die Angabe beider URLs ist ebenso optional wie req_perms. Sind die URLs nicht gesetzt, wird die Referer-Seite verwendet. Verweigere ich der Applikation den Zugriff werde ich übrigens im obigen Beispiel auf https://d-mueller.de/sorry.php?perms&selected_profiles=100000415342961 weitergeleitet. Stimme ich zu, lande ich bei https://d-mueller.de/thanks.php?perms=email,user_birthday,status_update,publish_stream,user_photos,user_videos&selected_profiles=100000415342961&installed=1&session=some-crazy-json-session-information So lässt sich per $perms = explode(",",$_GET['perms']); gut auswerten, welche Rechte der Benutzer der Applikation eingeräumt hat. Dann wird noch die Facebook-Session mit übergeben.

4) Logout-Möglichkeit

$logoutUrl = $facebook->getLogoutUrl(array('next' => 'https://d-mueller.de/loggedout.php')); 

Wie oben auch ist die next-URL wieder optional.

5) Alle Infos des Benutzers auslesen, auf die wir Zugriff haben

Habe in Kommentaren unter dem jeweiligen Aufruf den dazugehörigen Output gekleistert.

$session = $facebook->getSession();  if (!$session)  { 	print "Not Logged in or not yet allowed the app!"; 	print '<a href="'.$facebook->getLoginUrl().'">Login!</a>'; } else { 	print "Logged in!";		 	$me = $facebook->api('/me'); 	print_r($me); 	/* 	Array 	( 		[id] => 100000415342961 		[name] => David Müller 		[first_name] => David 		[last_name] => Müller 		[link] => http://www.facebook.com/mueller.dav 		[birthday] => 03/13/1989 		[education] => Array 			( 				[0] => Array 					( 						[school] => Array 							( 								[id] => 106191932753089 								[name] => HS Darmstadt 							) 	  						[type] => College 					) 	  			) 	  		[gender] => male 		[email] => mueller.dav@gmail.com 		[timezone] => 1 		[locale] => de_DE 		[verified] => 1 		[updated_time] => 2010-11-23T07:01:59+0000 	) 	*/ 	 	print_r($session); 	/* 	Array 	( 		[session_key] => 2.KNAv1M6c72HwXVjecs8f5g__.3600.1291136400-100000415342961 		[uid] => 100000415342961 		[expires] => 1291136400 		[secret] => dGqYF3hEUpvvVaWZ4T5QAw__ 		[access_token] => 182175161797277|2.KNAv1M6c72HwXVjecs8f5g__.3600.1291136400-100000415342961|DPZ2h8JmrDlB0_tWs0uMxGgbtK8 		[sig] => 82f24e389171741c571bb217874c382b 	) 	*/ } 

6) Facebook Query Language FQL

Die neue Art, wie die Facebook-API bedient werden sollte ist die FQL. Wer mit SQL einigermaßen vertraut ist, sollte sofort damit klarkommen. Erstmal ein Beispiel:

$fql_query  =   array( 	'method' => 'fql.query', 	'query' => 'SELECT uid, first_name, last_name, pic_square, pic_big, sex FROM user WHERE uid = '.$facebook->getUser() ); $fql_info = $facebook->api($fql_query); print_r($fql_info); /* Array ( 	[0] => Array 		( 			[first_name] => David 			[last_name] => Müller 			[pic_big] => http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs168.ash2/41506_100000415342961_8052474_n.jpg 			[sex] => männlich 			[uid] => 100000415342961 			[pic_square] => http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs169.ash2/41534_100000415342961_1227664_q.jpg 		) ) */ 

Einfach, oder? Hier gibt es eine FQL Referenz mit allen möglichen Feldern und Tabellen, die ihr abfragen könnt. Mit FQL lässt sich so auch herausfinden, welche Berechtigungen ein Benutzer euch erteilt hat. Es ist nämlich nicht gesagt, dass eure App immer gleichviel darf – Ein Benutzer kann nach Belieben die Rechte eurer App einschränken. Deswegen lohnt sich für viele Aktionen ein Check. Der geht nach folgendem Schema:

$fql_query  =   array( 	'method' => 'fql.query', 	'query' => 'SELECT publish_stream FROM permissions WHERE uid = '.$facebook->getUser() ); $fql_info = $facebook->api($fql_query); print_r($fql_info); /* Array ( 	[0] => Array 		( 			[publish_stream] => 1 		) ) 

Bedeutet: Wir dürfen (immernoch) die Pinnwand des Benutzers vollkritzeln. Wie das geht? Siehe direkt untendrunter.

7) Auf Pinnwand des Benutzers schreiben

Am besten – wie unter Punkt 8 oben erwähnt – vorher prüfen, ob die App überhaupt noch die Berechtigung dazu hat.

$facebook->api('/'.$facebook->getUser().'/feed', 'post', array( 	'message' => 'Hey there! Message from the void.', 	'name' => 'Appname', 	'description' => 'Message description', 	'caption' => 'Some Caption', 	'picture' => 'http://img01.lachschon.de/images/78394_orly_owl.jpg', 	'link' => 'https://d-mueller.de' )); 

Sieht dann auf der Pinnwand so aus:

fb-post

8) Öffentliche Informationen beliebiger User auslesen

Auch wenn ein Benutzer eure Applikation nicht erlaubt hat, ist ein kleines Subset an Infos trotz allem öffentlich auslesbar. Dabei zum Testen einfach schauen, welche ID euer Profil hat (Facebook Profilseite besuchen) – bei mir http://www.facebook.com/mueller.dav.

$public = $facebook->api('/mueller.dav'); print_r($public); /* Array ( 	[id] => 100000415342961 	[name] => David Müller 	[first_name] => David 	[last_name] => Müller 	[link] => http://www.facebook.com/mueller.dav 	[gender] => male 	[locale] => de_DE ) */ 

9) Benutzerbild darstellen

<img src="https://graph.facebook.com/<?php echo $facebook->getUser(); ?>/picture"> 

getUser() liefert die Benutzer-ID des Users zurück (siehe letzter Schritt). Auch zum Laden des Benutzerbilds braucht man kein Einverständnis des Benutzers, ich könnte hier also beliebige Benutzer-IDs verwenden.

Clientseite

Prinzipiell geht alles, was auf der Serverseite ging ebenso mit Javascript. Auch der Zugriff auf die extrem mächtige Facebook Query Language. Es ist also immer abzuwägen, ob im jeweiligen Fall sinnvoller die serverseite oder die Clientseite zu verwenden ist.

1) Initialisierung

<div id="fb-root"></div> <script src="http://connect.facebook.net/de_DE/all.js"></script>  <script> FB.init({   appId   : 'your-appid',   status  : true, // check login status   cookie  : true, // enable cookies to allow the server to access the session   xfbml   : true // parse XFBML }); </script> 

Danach kanns losgehen! Eigentlich sehr analog zur Initialisierung der PHP-Klasse, blos das kein secret-key angegeben wird. Wichtig: Unbedingt auf das fb-root-div vor Aufruf von FB.init achten. Sonst hagelts Fehlermeldungen.

2) Überprüfen, ob ein Benutzer eingeloggt ist

Der Code sollte selbstsprechend sein.

FB.getLoginStatus(function(response) //callback { 	if (!response.session) 	{ 		alert("user is not logged in"); 		console.log(response); 		/* 		Object 			perms: null 			session: null 			status: "unknown" 		*/ 	} 	else 	{ 		alert("user is logged in"); 		console.log(response); 		/* 		Object 			perms: "{"extended":["status_update","photo_upload","video_upload","email","create_note","share_item","publi…" 			session: Object 				access_token: "182175161797277|2.k9LeCVa1qBVELkQXMuILkg__.3600.1291136400-100000415342961|ZtQwAJOTbOJe5Nf6nTWkb6PzA…" 				expires: 1291136400 				secret: "secretkey" 				session_key: "2.k9LeCVa1qBVELkQXMuILkg__.3600.1291136400-100000415342961" 				sig: "signature" 				uid: "100000415342961" 			status: "connected" 		*/ 	} }); 

3) Benutzer einloggen

Was hier passiert, ist das das typische Facebook-Login-Popup hochkommt. Es gibt 3 verschiedene Möglichkeiten, was nun passiert.

Login-Fenster

Login-Fenster

  1. Der Benutzer hat der App noch keinen Zugriff gewährt: Der Benutuzer loggt sich ein und erlaubt dann der App den Zugriff – oder eben nicht.
  2. Der Benutzer hat der App bereits den Zugriff erteilt:Er muss sich nur noch einloggen.
  3. Der Benutzer hat der App den Zugriff erteilt und kommt mit einer gültigen Session: Das Fenster geht sofort wieder zu und der User gilt als eingeloggt

FB.login(function(response) //callback { 	if (response.session)  	{ 		console.log(response); 		/* 		Object 			perms: "read_stream,publish_stream,offline_access", 			session: Object { session_key="b089d77c93b5e25689470537-100000415342961", uid="100000415342961", more...}, 			access_token: "182175161797277|b089d77...3qTMrJmGcQiXszuf2apUbOk", 			expires: 0, 			secret:	"secretkey", 			session_key: "b089d77c93b5e25689470537-100000415342961", 			sig: "signature". 			uid:	"100000415342961" 			status: "connected", 		*/  		if (response.perms)  		{ 			// user is logged in and granted some permissions. 		}  		else  		{ 			// user is logged in, but did not grant any permissions 		} 	}  	else  	{ 		// user is not logged in 	} }, {perms:'read_stream,publish_stream,offline_access'}); 

Hier fordern wir vom Benutzer die unten aufgelisteten Rechte. Er hat natürlich die Wahl, dies zu gestatten oder zu verneinen. Wie es auch kommt – wir haben die Wahl, in der Callback-Funktion auf alles entsprechend zu reagieren. Schön ist, dass sich Facebook selbst drum kümmert, ob der Benutzer die App erst erlauben muss oder ob er sich nur einloggen muss. Hat er die App noch nicht erlaubt, kommt nach dem Login einfach folgendes zusätzliches Formular, in dem der User die Vernetzung vornimmt:

Permissions

Permissions

Probleme mit dieser Art des Logins:

  • Da es ein Popup ist, kann es sein, dass der Popup-Blocker zuuschlägt
  • Unter Webkit kämpft das Facebook-Team gerade mit einem weniger charmanten Fehler, der den Login per Javascript auf die oben beschriebene Art nicht gestattet. Bisher (Stand 30.11.2010) ist das Problem noch nicht gelöst. Folgendes wird als Fehler geschmissen:
    webkit-problem

    webkit-problem

Es ist also gut zu überlegen, ob man das wirklich so und nicht per Weiterleitung zu Facebook und dortigem Login (beschrieben unter Serverseitig -> Punkt 3) oder mit dem noch folgenden Login-Button machen will.

4) Benutzer ausloggen

FB.logout(function(response) { 	console.log(response); 	/* 	Object 		perms: null 		session: null 		status: "unknown" 	*/ 	 	if (response.session) 	{ 		alert("logout failed"); 	} 	else 	{ 		alert("logout successfull"); 	} }); 

5) FQL

Geht eigentlich ganz genau analog zu PHP auch clientseitig.

FB.api({ 	method: 'fql.query', 	query: 'SELECT name, pic FROM profile WHERE id=' + FB.getSession().uid }, function(response) { 	console.log(response);     	/* 	Object 		name: "David Müller" 		pic: "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs169.ash2/41534_100000415342961_1227664_s.jpg" 	*/ });	 

Ist der Benutzer bei euch eingeloggt, kann auch alles an Infos ausgelesen werden, was euch gestattet wurde:

FB.api('/me', function(response)  { 	console.log(response); 	/* 	Object 		birthday: "03/13/1989" 		education: Array[1] 		email: "mueller.dav@gmail.com" 		first_name: "David" 		gender: "male" 		id: "100000415342961" 		last_name: "Müller" 		link: "http://www.facebook.com/mueller.dav" 		locale: "de_DE" 		name: "David Müller" 		timezone: 1 		updated_time: "2010-11-23T07:01:59+0000" 		verified: true 	*/ });	 

6) Event-Listener

Es ist auch möglich, im typischen Javascript-Style auf Events zu reagieren. Ist also ein Benutzer bei euch auf der Seite unterwegs, lässt sich so flexibel auf Events wie ein- und ausloggen reagieren.

FB.Event.subscribe('auth.login', function() { 	alert("user logged in"); });  FB.Event.subscribe('auth.logout', function() { 	alert("user logged out"); });  //everything that's changing, including login and logout FB.Event.subscribe('auth.sessionChange', function(response) { 	if (response.session)  	{ 		alert("user logged in"); 	}  	else  	{ 		alert("user logged out"); 	} }); 

7) Der Facebook-Login-Button

Neben der Weiterleitung zu Facebook sicherlich die beste Lösung zum User-Login: Der offizielle facebook-Login-Button. Garantiert auch gut unter Webkit. Durch die Angabe von xfbml: true in der init-Funktion (Schritt 1) wird folgender Code in den eleganten blauen Facebook-Login-Button verwandelt:

</script> function callback() { 	//check if user is really logged in / granted all permissions } </script> 		 <fb:login-button perms="email,user_birthday" onlogin="callback()"></fb:login-button>	   

Die perms sind genau wie der callback optional. Übrigens wird der callback unabhängig vom Erfolg des Logins aufgerufen. Wenn der Benutzer eurer App keine Rechte einräumt oder entnervt auf „abbrechen“ klickt, ist es eure Aufgabe, das im Callback zu überprüfen.

Das wars!

Die Auflistung der Möglichkeiten ist natürlich ganz und garnicht vollständig, aber das wichtigste sollte erschlagen sein. Für alles weitere gehts dann auf der offiziellen facebook-developers-Seite weiter.


Deprecated: Directive 'allow_url_include' is deprecated in Unknown on line 0