Cheeeeze!

Teil 5: Verwendung des Instagram API in PHP
Kommentare

Bislang waren die Informationen (abgesehen vom Ort) nicht für den aktuellen Nutzer personalisiert. Das API ermöglicht Ihnen es jedoch auch, Anfragen im Namen des Benutzers zu stellen. Dazu kommt eine OAuth2-Authentifizierung zum Einsatz.

Details zum OAuth2-Protokoll finden Sie hier, in diesem Artikel werden Sie nur die nötigsten Basics kennen lernen, die Sie benötigen, um die Authentifzierung durchzuführen. Der Ablauf bei der Instagram-Authentifizierung besteht (vereinfacht) immer aus den folgenden Schritten:

  • Wenn der Kunde noch nicht bei Ihrer Anwendung authentifiziert ist, so schicken Sie ihn zu Instagram, damit er sich dort einloggt und Ihrer Anwendung Zugriff auf seine Daten erlaubt.
  • Wenn der Kunde Ihrer Anwendung den Zugriff auf seine Daten erlaubt, so schickt Instagram den Nutzer wieder zu Ihrer Anwendung zurück und übergibt Ihnen einen Code im URL.
  • Mithilfe dieses Codes machen Sie einen Aufruf beim Instagram-API und erhalten dabei ein Access-Token zurück.
  • Dieses Access-Token verwenden Sie nun bei den folgenden Aufrufen des APIs, um die Anfrage in Namen des Benutzers zu stellen.

OAuth2 und Instragram

Der URL, auf dem der Kunde die Autorisierung für Ihre Anwendung vornehmen kann, ist folgender:

https://api.instagram.com/oauth/authorize/?client_id=c15f...dd9&redirect_uri=http...usergram.php&response_type=code

Diesen URL rufen Sie jedoch nicht aus PHP heraus auf, sondern schicken den Kunden im Browser zum URL. Das können Sie entweder über einen einfachen Link auf Ihrer Website machen (der klassische „Sign-in with .“-Link) oder verwenden direkt einen Redirect.

Neben der Client-ID, die Sie bislang schon bei den Calls verwendet haben, müssen Sie beim Aufruf des URL auch einen redirect_uri-Parameter angeben. Dieser teilt Instagram mit, wohin der Benutzer geschickt werden soll, wenn die Autorisierung erfolgreich war. Hier kommt die Redirect-URI wieder ins Spiel, die Sie bei der Registrierung des Clients angeben mussten. Der redirect_uri-Parameter muss einen URL unterhalb der Redirect-URI aus der Konfiguration sein, wodurch sichergestellt ist, dass der Code nicht an eine andere Website übermittelt wird. Optional können Sie bei diesem URL noch einen scope-Paramter anhängen, mit dem Sie angeben möchten, was Ihre Anwendung im Namen des Nutzers tun möchte. Als Default-Wert wird hier immer der Basic Scope verwendet, mit dem Sie Daten abfragen können, jedoch keine Aktionen (Likes, anderen Benutzern folgen etc.) durchführen können.

Um die Authentifizierung in PHP umzusetzen, erweitern Sie nun die Instagram-Klasse. Als Erstes erweitern Sie den Konstruktur, sodass er auch das Client-Secret (wird später benötigt) und den Redirect-URL akzeptiert:

public function __construct($clientId, $clientSecret, $redirectUrl) {
  $this->clientId = $clientId;
  $this->clientSecret = $clientSecret;
  $this->redirectUrl = $redirectUrl;
}

Danach fügen Sie eine Methode ein, die den URL für die Autorisierung Ihres URL generiert, in dem Sie Client-ID und Redirect-URI ergänzt:

public function getAuthorizationUrl() {
  $url = sprintf("https://api.instagram.com/oauth/authorize/?client_id=%s&redirect_uri=%s&response_type=code",
  $this->clientId, urlencode($this->redirectUrl));
  return $url;
}

Zusätzlich erstellen Sie noch zwei Hilfsmethoden, um den Access Token zu speichern und auszulesen, falls Sie ihn einmal erhalten haben – damit Sie nicht für jeden Aufruf immer wieder einen neuen Token von Instagram anfordern müssen. Für das einfache Beispiel speichern Sie den erhaltenen Token in einer lokalen Datei. In einer echten Anwendung speichern Sie den Token für den gerade authentifizierten Benutzer sicherlich in der Benutzertabelle Ihrer Datenbank. Eine andere Möglichkeit (wenn Sie zum Beispiel keine eigene Benutzerverwaltung haben) ist die Speicherung in der Session.

protected function getAccessTokenFromStorage() {
  $token = @file_get_contents(self::TOKEN_FILE);
  if ($token === false) {
    return null;
  }
  return $token;
}

Auch hier gilt wieder, dass im Beispiel auf Fehlerbehandlung verzichtet wurde, was Sie in Ihrer Anwendung nachholen sollten. Genau so simpel wird das Speichern des Tokens implementiert.

protected function storeAccessToken($token) {
  file_put_contents(self::TOKEN_FILE, $token);
}

Nun sind Sie so weit, dass Sie sich an die Implementierung einer Methode machen können, die versucht, die Authentifizierung über verschiedene Wege durchzuführen. In dieser authenticate()-Methode prüfen Sie als Erstes, ob sie lokal schon einen Token vorliegen haben. Wenn ja, laden Sie den Token, speichern ihn in der Instagram-Instanz und beenden die Methode. Falls nicht, prüfen Sie, ob der Nutzer von Instagram auf Ihre Seite zurückgeschickt wurde. Das erkennen Sie daran, ob der code-Parameter im URL übergeben wurde. Ist dies der Fall, holen Sie sich mithilfe dieses Codes das Access-Token von Instagram (dazu später mehr). Ist kein code-Parameter am URL, kann keine Authentifizierung durchgeführt werden und Sie geben false zurück (Listing 6).

Listing 6

public function authenticate() {
  $token = $this->getAccessTokenFromStorage();
  if ($token !== null) {
    $this->accessToken = $token;
    return true;
  }
  if ($_GET['code']) {
    $token = $this->getAccessTokenFromInstagram($_GET['code']);
    if ($token !== null) {
      $this->accessToken = $token;
      $this->storeAccessToken($token);
      return true;
    }
  }
  return false;
}

Diese Methode verwenden Sie nun in Ihrer Applikation:

$instagram = new Instagram($config['clientId'],
                           $config['clientSecret'],
                           $config['redirectUrl']);
$auth = $instagram->authenticate();

War die Authentifizierung nicht erfolgreich, zeigen Sie dem Nutzer einen Link zur Autorisierungsseite von Instagram an:

if ($auth === false) {
  $url = $instagram->getAuthorizationUrl();
  printf('
<a class="btn btn-primary btn-large" href="%s"> Sign in with Instagram »</a>
', $url);
}

Abbildung 6 zeigt Ihnen das Ergebnis in diesem Fall.

Nachdem sich der Benutzer bei Instagram angemeldet hat, wird er gefragt, ob er Ihrer Anwendung Zugriff auf die eigenen Daten geben möchte. Abbildung 7 zeigt Ihnen, wie die entsprechende Seite aussieht.

Abb. 7: Die Freigabe auf der Instagram-Seite

Abb. 7: Die Freigabe auf der Instagram-Seite

Hat der Benutzer Ihrer Anwendung die Genehmigung erteilt, in seinem Namen Anfragen an das API zu erstellen, erfolgt ein Redirect zurück an Ihre Applikation und der code-Parameter wird angehängt. Zeit also, die Methode zu implementieren, mit der Sie mithilfe dieses Codes das Access-Token erhalten. Dazu müssen Sie einen POST-Request an den URL https://api.instagram.com/oauth/access_token senden und dabei Client-ID, Client-Secret, Code und Redirect-URL übermitteln. Wenn alle Daten korrekt waren, erhalten Sie eine JSON-Struktur, die ein Access Token enthält. Listing 7 zeigt Ihnen, wie Sie den Request absenden können und die Antwort parsen. Die zuvor implementierte authenticate()-Methode speichert diesen Token dann lokal und innerhalb der Instagram-Instanz.

Listing 7

protected function getAccessTokenFromInstagram($code) {
$data = array(
  'client_id' => $this->clientId,
  'client_secret' => $this->clientSecret,
  'redirect_uri' => $this->redirectUrl,
  'code' => $code,
  'grant_type' => 'authorization_code'
  );
  $data = http_build_query($data);
  $context_options = array (
  'http' => array (
  'method' => 'POST',
  'header'=> "Content-type: application/x-www-form-urlencodedrn",
  'content' => $data
    )
  );
  $context = stream_context_create($context_options);
  $json = file_get_contents('https://api.instagram.com/oauth/access_token', false, $context);
  if ($json === false) {
    return null;
  }
  $data = json_decode($json);
  return $data->access_token;
}

Nun können Sie weitere Methoden zu Ihrer Instagram-Klasse hinzufügen, die Informationen zum aktuellen Benutzer abfragen. Eine davon ermittelt zum Beispiel Basisinformationen (wie Name, Anzahl der Follower, Anzahl der Fotos) zu einem User:

  $url = sprintf("https://api.instagram.com/v1/users/%s", $userId);
  $url = $this->signUrl($url);
  return $this->getUrl($url);
}

Im Gegensatz zu den bisherigen Methoden, die das API abfragen, wird hier keine Client-ID an den URL gehängt. Stattdessen wird die Hilfsmethode signUrl() aufgerufen. In dieser Methode wird dem URL das Access Token hinzugefügt, sofern es existiert. Ansonsten wird die Client-ID ergänzt. Listing 8 zeigt die Implementierung. Auch wenn nicht jeder Endpoint des API ein personalisiertes Access Token verlangt, ist es sinnvoll, es zu verwenden. Damit wird der Request nicht auf das Gesamtlimit von 5000 Abfragen, die Ihre Applikation pro Stunde durchführen darf, angerechnet, sondern das Limit gilt für jeden einzelnen Nutzer.

Abb. 8: Personalisierte Informationen zum aktuellen Benutzer

Abb. 8: Personalisierte Informationen zum aktuellen Benutzer

Listing 8

public function __construct($clientId, $clientSecret, $redirectUrl) {
  $this->clientId = $clientId;
  $this->clientSecret = $clientSecret;
  $this->redirectUrl = $redirectUrl;
}

Listing 9 zeigt drei weitere Methoden, die Informationen zu einem Nutzer abfragen. Dazu gehören der Feed des aktuellen Benutzers (also seine eigenen Fotos und die Fotos von Nutzern, denen er folgt, in chronologischer Reihenfolge), die Fotos des aktuellen Nutzers und Fotos, die dem aktuellen Nutzer gefallen. Mithilfe dieser Methoden können Sie nun nach erfolgreicher Authentifizierung des Benutzers eine Übersicht mit den wichtigsten Daten zum aktuellen Nutzer darstellen, wie Ihnen Abbildung 8 zeigt. Somit haben Sie schon ein Webinterface für Instagram implementiert, das weitaus mehr Features als die offizielle Instagram-Website bietet.

Listing 9

public function __construct($clientId, $clientSecret, $redirectUrl) {
  $this->clientId = $clientId;
  $this->clientSecret = $clientSecret;
  $this->redirectUrl = $redirectUrl;
}

Weitere Möglichkeiten

In diesem Artikel konnten die Funktionalitäten des Instragram-API nur angerissen werden. Weitere Features umfassen auch das Hinzufügen, Löschen oder Bearbeiten von Kommentaren, Likes und Tags oder auch die Verwaltung der Beziehungen der Benutzer untereinander. Auch im Bereich Location-based Services bietet das API noch interessante Features, da beim Upload eines Fotos nicht nur die geografische Länge und Breite angegeben werden kann, sondern explizit ein Ort, an dem das Foto geschossen wurde. Anhand dieser Informationen können Sie explizit nach Fotos von einem bestimmten Ort suchen. Diese Orte werden mit der Foursquare-Datenbank verknüpft, sodass Sie den Fotos noch mehr Kontext verleihen können.

Das interessanteste Feature ist jedoch sicher der Subscription-Mechanismus mit dem Sie automatisch informiert werden können, wenn neue Fotos, die für Sie interessant sind, hochgeladen werden. Dieses Abonnement funktioniert auf Benutzer- und Tag-Ebene, aber auch für Locations und geografische Regionen. Um diese Funktionalität zu implementieren, setzt Instagram auf das Pubsubhubbub-Protokoll.

Sollten Sie Instagram-Fotos in Ihrer Website auf Basis von Links (z. B. in Kommentaren) einbetten wollen, so sind die Embedding-Endpoints des API für Sie interessant. Twitter nutzt diese so, dass Sie die Twitter-Website zum Öffnen eines in Twitter geposteten Fotos nicht mehr verlassen müssen.

Stephan Schmidt ist Head of Web Sales Development bei der 1&1 Internet AG und arbeitet seit über 10 Jahren mit PHP. Wer ihm auf Instagram folgen und immer wieder neue Fotos von Cupcakes und Burgern sehen möchte, findet ihn dort unter dem Usernamen „schst“.
Alle Teile: Teil 1, Teil 2, Teil 3, Teil 4, Teil 5
Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -