{"id":420,"date":"2010-11-30T22:57:07","date_gmt":"2010-11-30T21:57:07","guid":{"rendered":"https:\/\/d-mueller.de\/blog\/?p=420"},"modified":"2016-01-11T23:11:47","modified_gmt":"2016-01-11T22:11:47","slug":"facebook-api-tutorial","status":"publish","type":"post","link":"https:\/\/d-mueller.de\/blog\/facebook-api-tutorial\/","title":{"rendered":"Facebook API &#8211; Tutorial"},"content":{"rendered":"<p>Eins vorweg: Die Facebook API ist so m\u00e4chtig, dass man locker auf der API basierend ein zweites Facebook hochziehen k\u00f6nnte, 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 <b>serverseitige<\/b> (PHP) als auch die <b>clientseitige<\/b> (Javascript) Kommunikation mit Facebook anhand von Codeschnippseln beschreiben. Dabei verwende ich nur die Techniken, die laut Facebook noch verwendet werden sollten.<\/p>\n<h2>Getting Started<\/h2>\n<p>Als allererstes muss mal ein API Key her. Das geht <a href=\"http:\/\/developers.facebook.com\/setup\/\">hier<\/a>. Dabei muss ein &#8222;App-Name&#8220; vergeben werden und eine Domain spezifiziert werden. <b>Wichtig:<\/b> Nur Requests, die wirklich von der angegebenen Domain kommen, werden von Facebook zugelassen. Diese Domain kann allerdings jederzeit <a href=\"http:\/\/www.facebook.com\/developers\/apps.php\">in eurem Developers-Account<\/a> ge\u00e4ndert werden und auch <i>http:\/\/localhost\/<\/i> geht durch. Dort kriegt ihr auch einen &#8222;secret-key&#8220;, der ebenfalls wichtig ist.<\/p>\n<h2>Serverseite<\/h2>\n<h4>1) Facebook-Klasse und Zertifikat herunterladen<\/h4>\n<p>Auf der <a href=\"https:\/\/github.com\/facebook\/facebook-php-sdk\/tree\/master\/src\">Github Seite<\/a> die <i>facebook.php<\/i> und das Zertifikat herunterladen. Die Klasse werden wir f\u00fcr die API-Kommunikation brauchen und diese braucht wiederum das Zertikat. Achja, unbedingt CURL in der php.ini aktivieren!<\/p>\n<h4>2) Initialisierung<\/h4>\n<p>Der Konstruktor der Facebook-Klasse verlangt nach eurer App-ID und dem Secret-Key, den ihr beim Anmelden mitgeteilt bekommen habt.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$facebook = new Facebook(array(\r\n  &#039;appId&#039;  =&gt; &#039;eure-app-id&#039;,\r\n  &#039;secret&#039; =&gt; &#039;euer-secret-key&#039;,\r\n  &#039;cookie&#039; =&gt; true\r\n));\r\n<\/pre>\n<p>Jetzt kanns losgehen!<\/p>\n<h4>3) Login-M\u00f6glichkeit<\/h4>\n<p>Facebook Connect ist ein <a href=\"http:\/\/de.wikipedia.org\/wiki\/OAuth\">OAuth<\/a>-Dienst, der es Benutzern erm\u00f6glicht, sich auf eurer Seite \u00fcber Facebook einzuloggen. Diese melden sich dann mit ihrem Facebook Konto an und gew\u00e4hren dadurch eurer Webseite Zugriff auf gewisse Daten ihres Profils. Das geht wie folgt:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$url = $facebook-&gt;getLoginUrl(array(\r\n\t&#039;req_perms&#039; =&gt; &#039;email,user_birthday,status_update,user_photos,user_videos,publish_stream&#039;,\r\n\t&#039;next&#039; =&gt; &#039;https:\/\/d-mueller.de\/thanks.php&#039;,\r\n\t&#039;cancel_url&#039; =&gt; &#039;https:\/\/d-mueller.de\/sorry.php&#039; \r\n));\r\n\r\nprint &#039;&lt;a href=&quot;&#039;.$url.&#039;&quot;&gt;Login!&lt;\/a&gt;&#039;;\r\n<\/pre>\n<p>Ein Klick auf den Login-Link leitet den Benutzer zu facebook weiter, wo er eurer App die Befugnis erteilen kann, <i>seine E-Mail, seinen Geburtstag, seine Statusupdates und seine Fotos \/ Videos<\/i> einzusehen. Weiterhin fordern wir noch das Privileg, auch Posts auf die Pinnwand des Nutzers schreiben zu d\u00fcrfen. Das ist nat\u00fcrlich f\u00fcr ein simples Login v\u00f6llig \u00fcbertrieben und verschreckt Benutzer eher. Werden keine <i>req_perms<\/i> angegeben, ist Zugriff auf die \u00f6ffentlichen Angaben des Users gestattet. Ist ja eigentlich auch ausreichend. Facebook sagt dazu<\/p>\n<blockquote><p>By default, your application can access all public data in a user&#8217;s profile, including her name, profile picture, gender, and friends<\/p><\/blockquote>\n<p>Zur <i>next<\/i>-URL wird weitergeleitet, nachdem der Benutzer akzeptiert hat. Zur <i>cancel_url<\/i>, wenn er verweigert hat. Die Angabe beider URLs ist ebenso optional wie <i>req_perms<\/i>. Sind die URLs nicht gesetzt, wird die Referer-Seite verwendet. Verweigere ich der Applikation den Zugriff werde ich \u00fcbrigens im obigen Beispiel auf <\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">https:\/\/d-mueller.de\/sorry.php?perms&amp;selected_profiles=100000415342961<\/pre>\n<p> weitergeleitet. Stimme ich zu, lande ich bei <\/p>\n<pre data-enlighter-language=\"enlighter\" class=\"EnlighterJSRAW\">https:\/\/d-mueller.de\/thanks.php?perms=email,user_birthday,status_update,publish_stream,user_photos,user_videos&amp;selected_profiles=100000415342961&amp;installed=1&amp;session=some-crazy-json-session-information<\/pre>\n<p> So l\u00e4sst sich per <\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">$perms = explode(&quot;,&quot;,$_GET[&#039;perms&#039;]);<\/pre>\n<p> gut auswerten, welche Rechte der Benutzer der Applikation einger\u00e4umt hat. Dann wird noch die Facebook-Session mit \u00fcbergeben.<\/p>\n<h4>4) Logout-M\u00f6glichkeit<\/h4>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$logoutUrl = $facebook-&gt;getLogoutUrl(array(&#039;next&#039; =&gt; &#039;https:\/\/d-mueller.de\/loggedout.php&#039;));\r\n<\/pre>\n<p>Wie oben auch ist die <i>next<\/i>-URL wieder optional. <\/p>\n<h4>5) Alle Infos des Benutzers auslesen, auf die wir Zugriff haben<\/h4>\n<p>Habe in Kommentaren unter dem jeweiligen Aufruf den dazugeh\u00f6rigen Output gekleistert.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$session = $facebook-&gt;getSession();\r\n\r\nif (!$session) \r\n{\r\n\tprint &quot;Not Logged in or not yet allowed the app!&quot;;\r\n\tprint &#039;&lt;a href=&quot;&#039;.$facebook-&gt;getLoginUrl().&#039;&quot;&gt;Login!&lt;\/a&gt;&#039;;\r\n}\r\nelse\r\n{\r\n\tprint &quot;Logged in!&quot;;\t\t\r\n\t$me = $facebook-&gt;api(&#039;\/me&#039;);\r\n\tprint_r($me);\r\n\t\/*\r\n\tArray\r\n\t(\r\n\t\t[id] =&gt; 100000415342961\r\n\t\t[name] =&gt; David M\u00fcller\r\n\t\t[first_name] =&gt; David\r\n\t\t[last_name] =&gt; M\u00fcller\r\n\t\t[link] =&gt; http:\/\/www.facebook.com\/mueller.dav\r\n\t\t[birthday] =&gt; 03\/13\/1989\r\n\t\t[education] =&gt; Array\r\n\t\t\t(\r\n\t\t\t\t[0] =&gt; Array\r\n\t\t\t\t\t(\r\n\t\t\t\t\t\t[school] =&gt; Array\r\n\t\t\t\t\t\t\t(\r\n\t\t\t\t\t\t\t\t[id] =&gt; 106191932753089\r\n\t\t\t\t\t\t\t\t[name] =&gt; HS Darmstadt\r\n\t\t\t\t\t\t\t)\r\n\t \r\n\t\t\t\t\t\t[type] =&gt; College\r\n\t\t\t\t\t)\r\n\t \r\n\t\t\t)\r\n\t \r\n\t\t[gender] =&gt; male\r\n\t\t[email] =&gt; mueller.dav@gmail.com\r\n\t\t[timezone] =&gt; 1\r\n\t\t[locale] =&gt; de_DE\r\n\t\t[verified] =&gt; 1\r\n\t\t[updated_time] =&gt; 2010-11-23T07:01:59+0000\r\n\t)\r\n\t*\/\r\n\t\r\n\tprint_r($session);\r\n\t\/*\r\n\tArray\r\n\t(\r\n\t\t[session_key] =&gt; 2.KNAv1M6c72HwXVjecs8f5g__.3600.1291136400-100000415342961\r\n\t\t[uid] =&gt; 100000415342961\r\n\t\t[expires] =&gt; 1291136400\r\n\t\t[secret] =&gt; dGqYF3hEUpvvVaWZ4T5QAw__\r\n\t\t[access_token] =&gt; 182175161797277|2.KNAv1M6c72HwXVjecs8f5g__.3600.1291136400-100000415342961|DPZ2h8JmrDlB0_tWs0uMxGgbtK8\r\n\t\t[sig] =&gt; 82f24e389171741c571bb217874c382b\r\n\t)\r\n\t*\/\r\n}\r\n<\/pre>\n<h4>6) Facebook Query Language FQL<\/h4>\n<p>Die <i>neue<\/i> Art, wie die Facebook-API bedient werden sollte ist die FQL. Wer mit SQL einigerma\u00dfen vertraut ist, sollte sofort damit klarkommen. Erstmal ein Beispiel:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$fql_query  =   array(\r\n\t&#039;method&#039; =&gt; &#039;fql.query&#039;,\r\n\t&#039;query&#039; =&gt; &#039;SELECT uid, first_name, last_name, pic_square, pic_big, sex FROM user WHERE uid = &#039;.$facebook-&gt;getUser()\r\n);\r\n$fql_info = $facebook-&gt;api($fql_query);\r\nprint_r($fql_info);\r\n\/*\r\nArray\r\n(\r\n\t[0] =&gt; Array\r\n\t\t(\r\n\t\t\t[first_name] =&gt; David\r\n\t\t\t[last_name] =&gt; M\u00fcller\r\n\t\t\t[pic_big] =&gt; http:\/\/profile.ak.fbcdn.net\/hprofile-ak-snc4\/hs168.ash2\/41506_100000415342961_8052474_n.jpg\r\n\t\t\t[sex] =&gt; m\u00e4nnlich\r\n\t\t\t[uid] =&gt; 100000415342961\r\n\t\t\t[pic_square] =&gt; http:\/\/profile.ak.fbcdn.net\/hprofile-ak-snc4\/hs169.ash2\/41534_100000415342961_1227664_q.jpg\r\n\t\t)\r\n)\r\n*\/\r\n<\/pre>\n<p>Einfach, oder? Hier gibt es eine <a href=\"http:\/\/developers.facebook.com\/docs\/reference\/fql\/\">FQL Referenz<\/a> mit allen m\u00f6glichen Feldern und Tabellen, die ihr abfragen k\u00f6nnt. Mit FQL l\u00e4sst sich so auch herausfinden, welche Berechtigungen ein Benutzer euch erteilt hat. Es ist n\u00e4mlich nicht gesagt, dass eure App immer gleichviel darf &#8211; Ein Benutzer kann nach Belieben die Rechte eurer App einschr\u00e4nken. Deswegen lohnt sich f\u00fcr viele Aktionen ein Check. Der geht nach folgendem Schema:<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$fql_query  =   array(\r\n\t&#039;method&#039; =&gt; &#039;fql.query&#039;,\r\n\t&#039;query&#039; =&gt; &#039;SELECT publish_stream FROM permissions WHERE uid = &#039;.$facebook-&gt;getUser()\r\n);\r\n$fql_info = $facebook-&gt;api($fql_query);\r\nprint_r($fql_info);\r\n\/*\r\nArray\r\n(\r\n\t[0] =&gt; Array\r\n\t\t(\r\n\t\t\t[publish_stream] =&gt; 1\r\n\t\t)\r\n)\r\n<\/pre>\n<p>Bedeutet: Wir d\u00fcrfen (immernoch) die Pinnwand des Benutzers vollkritzeln. Wie das geht? Siehe direkt untendrunter.<\/p>\n<h4>7) Auf Pinnwand des Benutzers schreiben<\/h4>\n<p>Am besten &#8211; wie unter Punkt 8 oben erw\u00e4hnt &#8211; vorher pr\u00fcfen, ob die App \u00fcberhaupt noch die Berechtigung dazu hat.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$facebook-&gt;api(&#039;\/&#039;.$facebook-&gt;getUser().&#039;\/feed&#039;, &#039;post&#039;, array(\r\n\t&#039;message&#039; =&gt; &#039;Hey there! Message from the void.&#039;,\r\n\t&#039;name&#039; =&gt; &#039;Appname&#039;,\r\n\t&#039;description&#039; =&gt; &#039;Message description&#039;,\r\n\t&#039;caption&#039; =&gt; &#039;Some Caption&#039;,\r\n\t&#039;picture&#039; =&gt; &#039;http:\/\/img01.lachschon.de\/images\/78394_orly_owl.jpg&#039;,\r\n\t&#039;link&#039; =&gt; &#039;https:\/\/d-mueller.de&#039;\r\n));\r\n<\/pre>\n<p>Sieht dann auf der Pinnwand so aus:<br \/>\n<div id=\"attachment_421\" style=\"width: 412px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/fb-post.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-421\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/fb-post.png\" alt=\"\" title=\"fb-post\" width=\"402\" height=\"171\" class=\"size-full wp-image-421\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/fb-post.png 402w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/fb-post-300x127.png 300w\" sizes=\"auto, (max-width: 402px) 100vw, 402px\" \/><\/a><p id=\"caption-attachment-421\" class=\"wp-caption-text\">fb-post<\/p><\/div><\/p>\n<h4>8) \u00d6ffentliche Informationen beliebiger User auslesen<\/h4>\n<p>Auch wenn ein Benutzer eure Applikation nicht erlaubt hat, ist ein kleines Subset an Infos trotz allem \u00f6ffentlich auslesbar. Dabei zum Testen einfach schauen, welche ID euer Profil hat (Facebook Profilseite besuchen) &#8211; bei mir <i>http:\/\/www.facebook.com\/mueller.dav<\/i>.<\/p>\n<pre data-enlighter-language=\"php\" class=\"EnlighterJSRAW\">\r\n$public = $facebook-&gt;api(&#039;\/mueller.dav&#039;);\r\nprint_r($public);\r\n\/*\r\nArray\r\n(\r\n\t[id] =&gt; 100000415342961\r\n\t[name] =&gt; David M\u00fcller\r\n\t[first_name] =&gt; David\r\n\t[last_name] =&gt; M\u00fcller\r\n\t[link] =&gt; http:\/\/www.facebook.com\/mueller.dav\r\n\t[gender] =&gt; male\r\n\t[locale] =&gt; de_DE\r\n)\r\n*\/\r\n<\/pre>\n<h4>9) Benutzerbild darstellen<\/h4>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;img src=&quot;https:\/\/graph.facebook.com\/&lt;?php echo $facebook-&gt;getUser(); ?&gt;\/picture&quot;&gt;\r\n<\/pre>\n<p><i>getUser()<\/i> liefert die Benutzer-ID des Users zur\u00fcck (siehe letzter Schritt). Auch zum Laden des Benutzerbilds braucht man kein Einverst\u00e4ndnis des Benutzers, ich k\u00f6nnte hier also beliebige Benutzer-IDs verwenden.<\/i><\/p>\n<h2>Clientseite<\/h2>\n<p>Prinzipiell geht alles, was auf der Serverseite ging ebenso mit Javascript. Auch der Zugriff auf die extrem m\u00e4chtige Facebook Query Language. Es ist also immer abzuw\u00e4gen, ob im jeweiligen Fall sinnvoller die serverseite oder die Clientseite zu verwenden ist.<\/p>\n<h4>1) Initialisierung<\/h4>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;div id=&quot;fb-root&quot;&gt;&lt;\/div&gt;\r\n&lt;script src=&quot;http:\/\/connect.facebook.net\/de_DE\/all.js&quot;&gt;&lt;\/script&gt;\r\n\r\n&lt;script&gt;\r\nFB.init({\r\n  appId   : &#039;your-appid&#039;,\r\n  status  : true, \/\/ check login status\r\n  cookie  : true, \/\/ enable cookies to allow the server to access the session\r\n  xfbml   : true \/\/ parse XFBML\r\n});\r\n&lt;\/script&gt;\r\n<\/pre>\n<p>Danach kanns losgehen! Eigentlich sehr analog zur Initialisierung der PHP-Klasse, blos das kein secret-key angegeben wird. <b>Wichtig:<\/b> Unbedingt auf das <i>fb-root<\/i>-div vor Aufruf von <i>FB.init<\/i> achten. Sonst hagelts Fehlermeldungen.<\/p>\n<h4>2) \u00dcberpr\u00fcfen, ob ein Benutzer eingeloggt ist<\/h4>\n<p>Der Code sollte selbstsprechend sein.<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\nFB.getLoginStatus(function(response) \/\/callback\r\n{\r\n\tif (!response.session)\r\n\t{\r\n\t\talert(&quot;user is not logged in&quot;);\r\n\t\tconsole.log(response);\r\n\t\t\/*\r\n\t\tObject\r\n\t\t\tperms: null\r\n\t\t\tsession: null\r\n\t\t\tstatus: &quot;unknown&quot;\r\n\t\t*\/\r\n\t}\r\n\telse\r\n\t{\r\n\t\talert(&quot;user is logged in&quot;);\r\n\t\tconsole.log(response);\r\n\t\t\/*\r\n\t\tObject\r\n\t\t\tperms: &quot;{&quot;extended&quot;:[&quot;status_update&quot;,&quot;photo_upload&quot;,&quot;video_upload&quot;,&quot;email&quot;,&quot;create_note&quot;,&quot;share_item&quot;,&quot;publi\u2026&quot;\r\n\t\t\tsession: Object\r\n\t\t\t\taccess_token: &quot;182175161797277|2.k9LeCVa1qBVELkQXMuILkg__.3600.1291136400-100000415342961|ZtQwAJOTbOJe5Nf6nTWkb6PzA\u2026&quot;\r\n\t\t\t\texpires: 1291136400\r\n\t\t\t\tsecret: &quot;secretkey&quot;\r\n\t\t\t\tsession_key: &quot;2.k9LeCVa1qBVELkQXMuILkg__.3600.1291136400-100000415342961&quot;\r\n\t\t\t\tsig: &quot;signature&quot;\r\n\t\t\t\tuid: &quot;100000415342961&quot;\r\n\t\t\tstatus: &quot;connected&quot;\r\n\t\t*\/\r\n\t}\r\n});\r\n<\/pre>\n<h4>3) Benutzer einloggen<\/h4>\n<p>Was hier passiert, ist das das typische Facebook-Login-Popup hochkommt. Es gibt 3 verschiedene M\u00f6glichkeiten, was nun passiert.<br \/>\n<div id=\"attachment_422\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Login-Fenster.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-422\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Login-Fenster-300x192.png\" alt=\"Login-Fenster\" title=\"Login-Fenster\" width=\"300\" height=\"192\" class=\"size-medium wp-image-422\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Login-Fenster-300x192.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Login-Fenster.png 641w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-422\" class=\"wp-caption-text\">Login-Fenster<\/p><\/div><\/p>\n<ol>\n<li><b>Der Benutzer hat der App noch keinen Zugriff gew\u00e4hrt:<\/b> Der Benutuzer loggt sich ein und erlaubt dann der App den Zugriff &#8211; oder eben nicht.<\/li>\n<li><b>Der Benutzer hat der App bereits den Zugriff erteilt:<\/b>Er muss sich nur noch einloggen.<\/li>\n<li><b>Der Benutzer hat der App den Zugriff erteilt und kommt mit einer g\u00fcltigen Session:<\/b> Das Fenster geht sofort wieder zu und der User gilt als eingeloggt<\/li>\n<\/ol>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\nFB.login(function(response) \/\/callback\r\n{\r\n\tif (response.session) \r\n\t{\r\n\t\tconsole.log(response);\r\n\t\t\/*\r\n\t\tObject\r\n\t\t\tperms: &quot;read_stream,publish_stream,offline_access&quot;,\r\n\t\t\tsession: Object { session_key=&quot;b089d77c93b5e25689470537-100000415342961&quot;, uid=&quot;100000415342961&quot;, more...},\r\n\t\t\taccess_token: &quot;182175161797277|b089d77...3qTMrJmGcQiXszuf2apUbOk&quot;,\r\n\t\t\texpires: 0,\r\n\t\t\tsecret:\t&quot;secretkey&quot;,\r\n\t\t\tsession_key: &quot;b089d77c93b5e25689470537-100000415342961&quot;,\r\n\t\t\tsig: &quot;signature&quot;.\r\n\t\t\tuid:\t&quot;100000415342961&quot;\r\n\t\t\tstatus: &quot;connected&quot;,\r\n\t\t*\/\r\n\r\n\t\tif (response.perms) \r\n\t\t{\r\n\t\t\t\/\/ user is logged in and granted some permissions.\r\n\t\t} \r\n\t\telse \r\n\t\t{\r\n\t\t\t\/\/ user is logged in, but did not grant any permissions\r\n\t\t}\r\n\t} \r\n\telse \r\n\t{\r\n\t\t\/\/ user is not logged in\r\n\t}\r\n}, {perms:&#039;read_stream,publish_stream,offline_access&#039;});\r\n<\/pre>\n<p>Hier fordern wir vom Benutzer die unten aufgelisteten Rechte. Er hat nat\u00fcrlich die Wahl, dies zu gestatten oder zu verneinen. Wie es auch kommt &#8211; wir haben die Wahl, in der Callback-Funktion auf alles entsprechend zu reagieren. Sch\u00f6n ist, dass sich Facebook selbst drum k\u00fcmmert, 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\u00e4tzliches Formular, in dem der User die Vernetzung vornimmt:<br \/>\n<div id=\"attachment_423\" style=\"width: 310px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Permissions.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-423\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Permissions-300x225.png\" alt=\"Permissions\" title=\"Permissions\" width=\"300\" height=\"225\" class=\"size-medium wp-image-423\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Permissions-300x225.png 300w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/Permissions.png 645w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-423\" class=\"wp-caption-text\">Permissions<\/p><\/div><\/p>\n<p><b>Probleme mit dieser Art des Logins:<\/b><\/p>\n<ul>\n<li>Da es ein Popup ist, kann es sein, dass der Popup-Blocker zuuschl\u00e4gt<\/li>\n<li>Unter Webkit k\u00e4mpft 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\u00f6st. Folgendes wird als Fehler geschmissen: <div id=\"attachment_425\" style=\"width: 483px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/webkit-problem.png\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-425\" src=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/webkit-problem.png\" alt=\"webkit-problem\" title=\"webkit-problem\" width=\"473\" height=\"305\" class=\"size-full wp-image-425\" srcset=\"https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/webkit-problem.png 473w, https:\/\/d-mueller.de\/blog\/wp-content\/uploads\/2010\/11\/webkit-problem-300x193.png 300w\" sizes=\"auto, (max-width: 473px) 100vw, 473px\" \/><\/a><p id=\"caption-attachment-425\" class=\"wp-caption-text\">webkit-problem<\/p><\/div><\/li>\n<\/ul>\n<p>Es ist also gut zu \u00fcberlegen, ob man das wirklich so und nicht per Weiterleitung zu Facebook und dortigem Login (beschrieben unter <i>Serverseitig -> Punkt 3<\/i>) oder mit dem noch folgenden Login-Button machen will.<\/p>\n<h4>4) Benutzer ausloggen<\/h4>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\nFB.logout(function(response)\r\n{\r\n\tconsole.log(response);\r\n\t\/*\r\n\tObject\r\n\t\tperms: null\r\n\t\tsession: null\r\n\t\tstatus: &quot;unknown&quot;\r\n\t*\/\r\n\t\r\n\tif (response.session)\r\n\t{\r\n\t\talert(&quot;logout failed&quot;);\r\n\t}\r\n\telse\r\n\t{\r\n\t\talert(&quot;logout successfull&quot;);\r\n\t}\r\n});\r\n<\/pre>\n<h4>5) FQL<\/h4>\n<p>Geht eigentlich ganz genau analog zu PHP auch clientseitig.<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\nFB.api({\r\n\tmethod: &#039;fql.query&#039;,\r\n\tquery: &#039;SELECT name, pic FROM profile WHERE id=&#039; + FB.getSession().uid\r\n},\r\nfunction(response)\r\n{\r\n\tconsole.log(response);    \r\n\t\/*\r\n\tObject\r\n\t\tname: &quot;David M\u00fcller&quot;\r\n\t\tpic: &quot;http:\/\/profile.ak.fbcdn.net\/hprofile-ak-snc4\/hs169.ash2\/41534_100000415342961_1227664_s.jpg&quot;\r\n\t*\/\r\n});\t\r\n<\/pre>\n<p>Ist der Benutzer bei euch eingeloggt, kann auch alles an Infos ausgelesen werden, was euch gestattet wurde:<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\nFB.api(&#039;\/me&#039;, function(response) \r\n{\r\n\tconsole.log(response);\r\n\t\/*\r\n\tObject\r\n\t\tbirthday: &quot;03\/13\/1989&quot;\r\n\t\teducation: Array[1]\r\n\t\temail: &quot;mueller.dav@gmail.com&quot;\r\n\t\tfirst_name: &quot;David&quot;\r\n\t\tgender: &quot;male&quot;\r\n\t\tid: &quot;100000415342961&quot;\r\n\t\tlast_name: &quot;M\u00fcller&quot;\r\n\t\tlink: &quot;http:\/\/www.facebook.com\/mueller.dav&quot;\r\n\t\tlocale: &quot;de_DE&quot;\r\n\t\tname: &quot;David M\u00fcller&quot;\r\n\t\ttimezone: 1\r\n\t\tupdated_time: &quot;2010-11-23T07:01:59+0000&quot;\r\n\t\tverified: true\r\n\t*\/\r\n});\t\r\n<\/pre>\n<h4>6) Event-Listener<\/h4>\n<p>Es ist auch m\u00f6glich, im typischen Javascript-Style auf Events zu reagieren. Ist also ein Benutzer bei euch auf der Seite unterwegs, l\u00e4sst sich so flexibel auf Events wie ein- und ausloggen reagieren.<\/p>\n<pre data-enlighter-language=\"js\" class=\"EnlighterJSRAW\">\r\nFB.Event.subscribe(&#039;auth.login&#039;, function() {\r\n\talert(&quot;user logged in&quot;);\r\n});\r\n\r\nFB.Event.subscribe(&#039;auth.logout&#039;, function() {\r\n\talert(&quot;user logged out&quot;);\r\n});\r\n\r\n\/\/everything that&#039;s changing, including login and logout\r\nFB.Event.subscribe(&#039;auth.sessionChange&#039;, function(response) {\r\n\tif (response.session) \r\n\t{\r\n\t\talert(&quot;user logged in&quot;);\r\n\t} \r\n\telse \r\n\t{\r\n\t\talert(&quot;user logged out&quot;);\r\n\t}\r\n});\r\n<\/pre>\n<h4>7) Der Facebook-Login-Button<\/h4>\n<p>Neben der Weiterleitung zu Facebook sicherlich die beste L\u00f6sung zum User-Login: Der offizielle facebook-Login-Button. Garantiert auch gut unter Webkit. Durch die Angabe von <i>xfbml: true<\/i> in der init-Funktion (Schritt 1) wird folgender Code in den eleganten blauen Facebook-Login-Button verwandelt:<\/p>\n<pre data-enlighter-language=\"html\" class=\"EnlighterJSRAW\">\r\n&lt;\/script&gt;\r\nfunction callback()\r\n{\r\n\t\/\/check if user is really logged in \/ granted all permissions\r\n}\r\n&lt;\/script&gt;\r\n\t\t\r\n&lt;fb:login-button perms=&quot;email,user_birthday&quot; onlogin=&quot;callback()&quot;&gt;&lt;\/fb:login-button&gt;\t  \r\n<\/pre>\n<p>Die <i>perms<\/i> sind genau wie der callback optional. \u00dcbrigens wird der callback unabh\u00e4ngig vom Erfolg des Logins aufgerufen. Wenn der Benutzer eurer App keine Rechte einr\u00e4umt oder entnervt auf &#8222;abbrechen&#8220; klickt, ist es eure Aufgabe, das im Callback zu \u00fcberpr\u00fcfen.<\/p>\n<h2>Das wars!<\/h2>\n<p>Die Auflistung der M\u00f6glichkeiten ist nat\u00fcrlich ganz und garnicht vollst\u00e4ndig, aber das wichtigste sollte erschlagen sein. F\u00fcr alles weitere gehts dann <a href=\"http:\/\/developers.facebook.com\/docs\/\">auf der offiziellen facebook-developers<\/a>-Seite weiter.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Eins vorweg: Die Facebook API ist so m\u00e4chtig, dass man locker auf der API basierend ein zweites Facebook hochziehen k\u00f6nnte, was durch die Facebook API gespeist wird. Leider gibt es aber auch zich verschiedene Quellen bei Facebook selbst. Vieles, was &hellip; <a href=\"https:\/\/d-mueller.de\/blog\/facebook-api-tutorial\/\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,12,3],"tags":[],"class_list":["post-420","post","type-post","status-publish","format-standard","hentry","category-php","category-javascript","category-webdev"],"_links":{"self":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/420","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/comments?post=420"}],"version-history":[{"count":0,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/posts\/420\/revisions"}],"wp:attachment":[{"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/media?parent=420"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/categories?post=420"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/d-mueller.de\/blog\/wp-json\/wp\/v2\/tags?post=420"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}