Artikelbild Produktbilder DSGVO
Webtechniken

DSGVO und Affiliate-APIs: Produktbilder DSGVO-konform einbinden [Update]




Nicht mehr lange bis die Übergangsphase der neuen Datenschutzgrundverordnung beendet ist. Am 25. Mai geht es los und viele Fragen sind immer noch ungeklärt. Zum Beispiel, ob die Einbindung der Produktbilder aus den APIs der Affiliate-Netzwerke erlaubt ist?

Die Nutzung der APIs verschiedener Affiliate-Netzwerke (Amazon, Afillinet, Zanox, Belboon etc.) hat den Vorteil, Preise und Produktdaten auf der eigenen Seite vollautomatisiert aktuell halten zu können.
Ein weiterer Vorteil, besonders mit Blick auf die DSGVO: der Link zu den Produkten setzt noch keinen Cookie – im Gegenteil zu vielen Werbebannern die direkt über das Netzwerk eingebettet werden. Amazon untersagt aber in seinen Richtlinien das Speichern der Produktbilder auf dem eigenen Server. Diese müssen also zur Darstellung auf der eigenen Seite über Amazons Server eingebunden werden.

Das führt aber leider zu Konflikten mit der DSGVO, da beim Abruf der Bilder über einen anderen Server die IP-Adressen der Nutzer übertragen werden. Und die IP-Adresse zählt zu den personenbezogenen Daten, die nicht ohne Einwilligung des Nutzers erhoben werden dürfen. Doppelt schlecht, wenn der Server dann auch noch außerhalb Europas steht.

Wie immer bei diesen Themen: Dies ist keine Rechtsberatung! Der Artikel zeigt lediglich Möglichkeiten, wie die bisherige Einbindung der Bilder weiterhin erlaubt sein kann.

Mögliche Lösungswege für die Einbindung von externen Bildern

Da durch die DSGVO momentan alle wie ein verrückter Hühnerhaufen von einem Totschlagthema (Google Fonts) zum Nächsten (Facebook Pixel) durcheinander laufen, bleiben neben den Hauptthemen manche Randthemen liegen.
Mir sind drei Lösungen eingefallen, die das Problem mit der Einbindung der Bilder vielleicht lösen.

Lösung 1: Berechtigtes Interesse?

Als Betreiber von Webseiten die Einnahmen erzielen sollen, ist man Unternehmer. Und um das Unternehmensziel verfolgen zu können (Einnahmen), wird nicht für alles eine Zustimmung des Nutzers benötigt, wenn diese im berechtigten Interesse des Unternehmers liegen.
Setzt ein Online-Shop Google Analytics oder Conversion-Tracking ein, um die Webseite zu optimieren, liegt das im berechtigten Interesse des Unternehmens.

Schlussendlich müsste es doch auch im berechtigten Interesse des Webseitenbetreibers liegen, die Produktbilder einbinden zu können. In dem Fall dürfte ein Hinweis darauf in der Datenschutzerklärung genügen?

Lösung 2: Die Zwei-Klick-Lösung (hmmmm….)

Bei YouTube-Videos, Social-Media-Buttons und anderem Tracking-Ungeziefer kommt man um eine Zwei-Klick-Lösung kaum herum. Werden diese Elemente mit dem normalen, zur Verfügung gestellten Code eingebunden, werden beim Aufruf der Seite auch Daten des Nutzers übertragen.

Abhilfe schafft eine Zwei-Klick-Lösung, damit der Nutzer explizit diesem Vorgang zustimmen kann. Erst nach dem „Ja“ sollten dann die Inhalte, in unserem Fall die Bilder, geladen werden. Wirklich praktisch für den Nutzer ist das aber nicht. Vor allem, wenn jede zweite Webseite nach einer solchen Erlaubnis fragt.

Lösung 3: Bilder von der eigenen Domain einbinden

Die URL des Bildes haben wir ja schon beim Abruf aus der API erhalten. Wird diese URL nun direkt im Quelltext der Webseite verwendet, wird beim Aufruf durch den Nutzer auch seine IP-Adresse übertragen.
Die dritte Lösung besteht einfach darin, hier einen Zwischenschritt (quasi einen Bilder-Proxy) über die eigene Domain einzubauen.

Die Auslieferung des Bildes übernimmt dann ein kleines PHP-Skript, welches sich einfach mit der URL als Parameter füttern lässt.

Also anstatt:

zu verwenden, wird das Skript mit Parameter aufgerufen. Das PHP-Skript holt die Grafikdatei und übermittelt so nur die IP der Subdomain an den Server des Bildes:

Das PHP-Skript könnte dann so aussehen:

Die dritte Möglichkeit würde ich bislang eigentlich vorziehen. Diese macht zwar mehr Arbeit als ein berechtigtes Interesse in Möglichkeit 1, dürfte aber rechtstechnisch wohl eher auf der sicheren Seite sein.

Umsetzung für Affiliate WordPress-Plugins

Hier auf dem Kritzelblog verwende ich für die Amazon-Links das Plugin Affiliate Toolkit Starter in der kostenlosen Version. In der aktuellen Version bezieht dieses die Bilder noch direkt von den Amazon-Servern. Mit dieser Lösung kann hier Abhilfe geschaffen werden, so oder ähnlich dürfte es auch bei anderen Plugins funktionieren.

Das oben gezeigte Skript lade ich als img.php in das Rootverzeichnis der Webseite. So das es immer über den direkten Aufruf https://www.domain.de/ erreichbar ist.

Den gesamten Plugin-Ordner lade ich vom Server herunter und suche nach den Teilen, mit denen die Bilder im Frontend angezeigt werden. Im Fall von Affiliate Toolkit sind diese sogar ganz einfach im Unterordner /templates zu finden.
Dort befindet sich an der Stelle wo die Bilder eingebunden werden, der Platzhalter %mediumimageurl%. Vor diesen muss nun der Skripaufruf gesetzt werden:

Betroffen sind beim Affiliate-Toolkit die Dateien wide.php, secondwide.php, bestseller.php und box.php.

Im folgenden Beispiel einfach mal mit der rechten Maustaste auf das Bild klicken und es einzeln anzeigen lassen. In der Adresszeile des Browsers befindet sich nun der Link zur img.php.

Wie geht Amazon damit um?

Da ich auf die Anfrage beim Amazon Partnerprogramm nach einem Auftragsverarbeitungsvertrag nur die Antwort „ich verstehe Ihre Frage nicht“ erhalten habe, sind die Mitarbeiter dort entweder wirklich sehr schlecht informiert, völlig desinteressiert oder die Partner sollen erstmal noch kurz gehalten werden.
Amazon prüft den Traffic, der von den Affiliates kommt. Wer in Facebook-Gruppen spammt, steht schnell vor einer Sperrung des Kontos. Ich würde also bei Lösung drei nicht empfehlen, die Bilder über irgendeine kryptische (Sub-)Domain zu ziehen, sondern über eine zum Projekt passende.

Wie der Zugriff auf die Amazon-API hergestellt werden kann, steht hier.

Also wenn das Projekt auf schaukelpferdchen-fuer-fritz.de liegt, dürfte die Subdomain bilder.schaukelpferdchen-fuer-fritz.de kein großes Aufsehen erregen.



15 Kommentare zu “DSGVO und Affiliate-APIs: Produktbilder DSGVO-konform einbinden [Update]

  1. Hallo, danke für den Artikel!

    Ich würde auch die Lösung #3 bevorzugen. Leider kenne ich mich nicht so gut mit der Einbindung per PHP aus. Ich bin aber bereit, etwas neues zu lernen.

    Wo genau muss ich denn das PHP-Skript einbinden, in der „functions.php“ meines WordPress Themes?

    Reicht es aus, wenn ich bei meinem Webhoster (All-Inkl) einfach eine Subdomain anlege, ohne WordPress zu installieren?

    Ich würde mich über eine Antwort freuen! :-)

    • Nur das Skript hilft dir nicht weiter. Wenn du WordPress verwendest, muss das Plugin oder Theme das lösen.

      • Hallo, danke für die Antwort! :-)

        Ich habe es mit deinem PHP-Skript hinbekommen. Das Skript habe ich ganz unten (unterste Zeile) in die „functions.php“ meines WordPress Themes eingefügt ohne „“, sondern einfach nur:

        $url = $_GET[‚url‘];
        if(strpos($url,“.jpg“))
        {
        header(„Content-Type: image/jpg“);
        }

        if(strpos($url,“.gif“))
        {
        header(„Content-Type: image/gif“);
        }

        if(strpos($url,“.png“))
        {
        header(„Content-Type: image/png“);
        }
        readfile($url);

        Ich nutze das ASA 1 (Amazon Simple Admin) Plugin (https://de.wordpress.org/plugins/amazonsimpleadmin/) für meine Produkte, die ich als Affiliate auf meiner Webseite in einer „Produktbox“ bewerbe.

        Dieses Plugin nutzt z.B. {$MediumImageUrl} um das Produktbild per API von Amazon auszulesen und es in einer Produktbox darzustellen.

        Ich habe das ganze ohne Subdomain gemacht, also das PHP-Skript in das Theme (functions.php) meiner Hauptdomain eingebaut.

        Mit dem HTML-Code konnte ich das Bild erfolgreich auf meiner Seite darstellen, auch ohne Subdomain. Drückt man im Chrome-Browser F12 für den Entwicklermodus, dann sieht man auch unter „Sources“, dass das Amazon Bild nicht mehr direkt vom AWS-Server (https://images-eu.ssl-images-amazon.com) geladen wird.

        Ich habe dann einfach in die CSS-Datei meines Plugins (ASA1) vor dem {$MediumImageUrl} den obigen Linkschnipsel eingefügt:

        Das hat auch funktioniert. Danke! :-)

        Jetzt habe ich noch ein PROBLEM…

        Bei mir erscheint oben über dem Header meiner Webseite folgender PHP Fehlercode: Warning: readfile(): Filename cannot be empty in …

        So wie ich es durch Recherche verstanden habe, ist bei $url = $_GET[‚url‘]; die url nicht definiert… oder wo liegt der Fehler?

        Außerdem kommen komische Zeichen über dem Header meiner Webseite, wenn ich das Bild in einem neuen Tab mit der URL „https://www.domain.de/img.php?url=linkzumbild“ öffne:

        P��dyS+#@袊(��(��(��(��(��(��� und so weiter…

        Tut mir Leid, dass mein Kommentar so lang geworden ist, aber du bist der einzige, der mir soweit in Deutsch weiterhelfen konnte und ich bin ja schon kurz vor der Lösung, weil ein Teil bereits funktioniert!

        Ich würde mich über eine Antwort freuen! DANKE :-)

        • Also erstmal super, aber ich fürchte die Zeichen entstehen dadurch, dass mittendrin nochmal ein Header definiert wird. Ehrlich gesagt wundert’s mich das überhaupt noch was auf der Seite erscheint.
          Ich weiß nicht genau wie ASA funktioniert, aber definitiv besser wäre es, wenn das Plugin wirklich die img.php?url=xyz aufrufen würde.
          Für einen ersten Test, versuch mal das ganze als Funktion in die functions.php zu setzen:

          function img($url){
          readfile($url);
          };
          (ungetestet)

          Dort, wo das Bild im Plugin geladen würde, müsste dann eben img($MediumImageUrl); hin.
          Den Header braucht die img.php nur, weil sie sich gegenüber dem Webserver als Bild ausgeben muss.

          • Danke, für die schnelle Antwort. :-)

            Ich habe es versucht, aber jetzt kommt kein Bild mehr, bestimmt habe ich es falsch eingesetzt.

            Also ich habe in die „functions.php“ folgendes eingesetzt:

            $url = $_GET[‚url‘];
            if(strpos($url,“.jpg“))
            {
            header(„Content-Type: image/jpg“);
            }

            if(strpos($url,“.gif“))
            {
            header(„Content-Type: image/gif“);
            }

            if(strpos($url,“.png“))
            {
            header(„Content-Type: image/png“);
            }
            function img($url){
            readfile($url);
            };

            und in die CSS-Datei des Plugins (für jede Produktbox gibt es immer ein Template, dass als CSS definiert ist) habe ich img($MediumImageUrl); eingesetzt, so sieht das bei mir aus:

            Oder muss ich img($MediumImageUrl); in die „functions.php“ des Plugins ASA1 setzen und nicht in die CSS-Datei?

            Danke für die Hilfe, ich glaube, ich stehe kurz vor der Lösung! :D

  2. Ergänzung: so habe ich es in die CSS-Datei eingefügt…

    img src=“img($MediumImageUrl);“

  3. Hey Steffen, ich habe es geschafft! :-)

    Ich habe den Fehler entdeckt bzw. verstanden. :-D

    Anstatt in die „functions.php“ meines Themes das PHP-Skript einzufügen, habe ich es in der „AsaFunctions.php“ meines Plugins ASA 1 probiert bzw. eingefügt. Und sehe da, es funktioniert einwandfrei, das Bild wird geladen, ohne PHP Fehlercode im Header und wenn ich die URL („https://www.domain.de/img.php?url=linkzumbild“) aufrufe, wird das Bild einzeln im Browser, wie jedes andere normale Bild angezeigt.

    Lösung: Nicht etwas an der „functions.php“ des Themes ändern, sondern direkt beim Plugin ansetzen, um gezielt etwas zu verändern!

    Ich habe im CSS-Code des Plugins für das jeweilige Template, das die Produktbox definiert, folgendes eingefügt: img src=“https://www.domain.de/img.php?url={$MediumImageUrl}“

    Genau so funktioniert alles ohne Probleme! Jetzt sollte es wegen der IP-Adresse denke ich mal keine Probleme mehr geben, weil ja nur meine IP von meiner Domain an Amazon (AWS) übermittelt wird, richtig?

    Somit ist meine Webseite jetzt auch komplett DSGVO konform, da ich keine Cookies, Tracker, Webfonts, unsichere Plugins, Kontaktformulare oder Kommentare nutze. Bis auf die Logfiles (anonymisiert) des Webhosters, die sind ja erlaubt!

    Nach langem Kopf zerbrechen und herumexperimentieren habe ich es als Anfänger, was PHP angeht, hinbekommen. Für den einen oder anderen wahrscheinlich eine sehr leichte Aufgabe, doch für mich nicht!

    PS: Vielleicht nutzt ja auch jemand anderes deiner Leser das „ASA 1“ Plugin für WordPress (da es kostenlos ist und die Amazon API ausliest) als Amazon Affiliate für seine eigene Webseite bzw. Nischenseite und vielleicht helfen ihm die vorherigen Kommentare bei der datenschutzkonformen Umsetzung!

    Vielen Dank für den Artikel und die Idee! :-)

  4. Ich war wieder zu voreilig, tut mir Leid! :(

    Das Bild lässt sich zwar öffnen aber oben über dem Header kommt wieder: Warning: readfile(): Filename cannot be empty in …

    Ich habe aber jetzt mal genauer gesucht und in der „AsaCore.php“ folgendes gefunden:

    $replace = array(
    $item->ASIN,
    ($item->SmallImage != null) ? $item->SmallImage->Url->getUri() : $no_img_url,
    ($item->SmallImage != null) ? $item->SmallImage->Width : 60,
    ($item->SmallImage != null) ? $item->SmallImage->Height : 60,
    ($item->MediumImage != null) ? $item->MediumImage->Url->getUri() : $no_img_url,
    ($item->MediumImage != null) ? $item->MediumImage->Width : 60,
    ($item->MediumImage != null) ? $item->MediumImage->Height : 60,
    ($item->LargeImage != null) ? $item->LargeImage->Url->getUri() : $no_img_url,
    ($item->LargeImage != null) ? $item->LargeImage->Width : 60,
    ($item->LargeImage != null) ? $item->LargeImage->Height : 60,

    Du meintest „Dort, wo das Bild im Plugin geladen würde, müsste dann eben img($MediumImageUrl); hin.“

    Wo genau sollte ich es einfügen, ich glaube du meinst nicht die CSS-Datei wo das Bild geladen wird, sondern die PHP-Datei?

    Sorry für die ganzen Kommentare…

  5. Hallo, ich habe eine andere Lösung gefunden! Ich speichere die Bilder doch auf meiner Festplatte und lade sie dann lokal auf meinem Server hoch.

    Du schreibst in deinem Artikel:

    „Amazon untersagt aber in seinen Richtlinien das Speichern der Produktbilder auf dem eigenen Server. Diese müssen also zur Darstellung auf der eigenen Seite über Amazons Server eingebunden werden.“

    Ich habe folgendes gefunden, das empfiehlt das Amazon PartnerNet selbst, was das „Kopieren“ von Bildern angeht:

    „Halten Sie die Maustaste über der gewünschten Schaltfläche gedrückt und wählen Sie den Befehl „Bild speichern unter…“. Speichern Sie die Grafik auf Ihrer Festplatte.“

    Hier kannst du es selber nachlesen: https://partnernet.amazon.de/help/topic/t8/a2

    Problem gelöst! :-)

    • Würde ich nicht machen, hier stehen die Bedingungen mit Sicherheit über irgendwelchen Tipps aus der Hilfefunktkion, die vielleicht schon seit Jahren da stehen.
      Zumal du damit das Problem hast, das die Bilder nicht immer aktuell sind und du das laut Bedingungen dann alle 24 Stunden nochmal machen kannst…

      Hast du mal angefragt wegen einem Update? Kannst mir auch gerne mal einen Link zur Seite senden.

  6. Ich habe gestern sehr viele Nischenseiten analysiert und festgestellt, dass zahlreiche Seitenbetreiber einfach die Produktbilder speichern und selbst auf ihrer Webseite hochladen. Im Impressum geben sie dann Amazon als Bildquelle an.

    Ich lass es lieber darauf ankommen, dass mich jemand wegen irgendeinem Produktbild von Amazon abmahnt oder dass Amazon mein Partnerkonto sperrt (was sehr unwahrscheinlich ist, weil dann hätten sie das bei allen anderen Webseiten, die ich analysiert habe, genau so tun müssen), anstatt die Produktbilder weiterhin so wie gewohnt aus der API auszulesen und dann noch Angst davor zu haben, wegen irgendwelchen IP-Adressen abgemahnt zu werden. Weil dies die DSGVO betrifft können die Strafen weit aus höher sein (Stichwort: 20 Millionen) und darauf lass ich es ungern ankommen.

    Wenn ich also die Wahrscheinlichkeit und das Risiko beider Varianten abschätze und vergleiche, dann würde ich Variante 1 (Bilder speichern und selbst hochladen) bevorzugen. Hier hätte ich im schlimmsten Fall noch eine berechtige Argumentationsgrundlage, weil Amazon ja selbst in seinen Artikel im Detail erklärt, wie ich die Bilder kopieren bzw. speicher kann.

    1. https://partnernet.amazon.de/help/topic/t15/a10
    2. https://partnernet.amazon.de/help/topic/t8/a2

    Da kann ich ja als Affiliate nichts dafür, wenn Amazon in seinem Partnerprogramm veraltete Tipps als Hilfefunktion bereitstellt, schließlich muss Amazon dafür sorgen, dass die Informationen rechtlich aktuell sind.

    Bei vielen Produkten, die ich schon seit Jahren in diversen Nischen bewerbe, hat sich das Porduktbild kaum oder gar nicht verändert, hier muss ich nicht alle 24 Stunden das Bild aktualisieren. Du sprichst von „laut Bedingungen“ eine Quelle wäre sehr hilfreich, dann könnte ich mir das Ganze nochmal genauer anschauen.

    Leider habe ich es nach hunderten Versuchen nicht ohne PHP Fehlercode (was meine Webseite in der Funktionalität total beeinträchtigt) hinbekommen.

    Wenn du mir sagen könntest, wie ich den Fehlercode (Warning: readfile():
    Filename cannot be empty in …) wegbekomme bzw. wo der Fehler liegt, dann würde ich es auf jeden Fall nochmal versuchen, weil es natürlich vom Zeitaufwand viel einfacher wäre, die Bilder per API auszulesen, anstatt jedes Produktbild nochmal einzeln hochzuladen. Es muss dann aber auch per API und img.php datenschutzkonform + ohne Fehlercode sein, sonst lohnt es sich nicht! :-)

    Die letzte Möglichkeit besteht darin, dass ich den Admin des ASA 1 Plugins kontaktiere und ihn frage, wie ich das mit den Produktbildern per PHP hinbekomme.

    Schöne Grüße! :-)

    • Hallo Franz,
      ich habe den Artikel überarbeitet. Am Beispiel des Affiliate-Toolkit Starter habe ich jetzt die Sachen angepasst. Das sollte sich so recht problemlos auch auf andere Plugins übertragen lassen.

      • Achja, super! :-)

        Dann probiere ich es noch mal aus, vielleicht klappt es jetzt! Ansonsten bleibt mir nichts anderes übrig, als vorerst die Produktbilder manuell abzuspeichern und hochzuladen. Dies dauert aber auch dementsprechend länger!

        • Sebastian

          Hey Franz, hey Steffen,

          vielen Dank für den Beitrag und eure Kommentare dazu. Ich habe generell das gleiche „Problem“ wie Franz. Nur als eine weitere Möglichkeit: Das vorgestellte Plugin Affiliate-Toolkit hat einen „Kompatibilitätsmodus“ für ASA 1 und 2. Es erkennt alle Shortcodes und kann in die Version vom Toolkit umgewandelt werden. Laut der Facebook-Gruppe vom Plugin-Besitzer soll auch die kostenlose Version diese Proxyumleitung noch vor dem 25. in einem Update als Auswahlmöglichkeit in den Einstellungen verpasst bekommen.

          Du könntest als relativ einfach umsteigen, ohne durch alle Beiträge gehen zu müssen.

          Falls das mit der kostenlosen Version nicht mehr ganz rechtzeitig passt und dir das Risiko zu groß wäre, gäbe es dann auch noch die Pro-Version, die das bereits jetzt kann mit Proxyumleitung.

          Oder du kannst es analog wie Steffen in seiner Beschreibung machen.

          • Hallo Steffen, hallo Franz,

            erstmal dir Steffen vielen Dank für den Artikel. Dieser hat mir bei ASA 1 sehr geholfen. Ich habe entsprechend deiner dritten Variante ASA 1 angepasst, da ich weder ASA 2 kaufen wollte noch warten möchte bis ASA 1 endlich aktualisiert wird.
            @Franz: Folgendes habe ich in der AsaCore.php angepasst (direkt vor bzw. in dem Array, den du weiter oben genannt hast):

            $domain_name = $_SERVER[‚SERVER_NAME‘];
            $add_url=’https://‘.$domain_name.’/img.php?url=‘;

            $newstr = substr_replace($customerReviews->imgTag, $add_url, 10, 0);
            $customerReviews->imgTag = $newstr;

            $placeholderStack = array(
            ‚ASIN‘ => $item->ASIN,
            ‚SmallImageUrl‘ => ($item->SmallImage != null) ? $add_url.$item->SmallImage->Url->getUri() : $no_img_url,

            ‚MediumImageUrl‘ => ($item->MediumImage != null) ? $add.$item->MediumImage->Url->getUri() : $no_img_url,

            ‚LargeImageUrl‘ => ($item->LargeImage != null) ? $add_url.$item->LargeImage->Url->getUri() : $no_img_url,

            Die Domainabfrage habe ich erstellt, damit auch bei Multisites die Domain der jeweiligen Unterseite verwendet wird.

            $newstr = substr_replace($customerReviews->imgTag, $add_url, 10, 0);
            $customerReviews->imgTag = $newstr;
            Dieser Abschnitt ergänzt die URL der Rating-Sternchen um die Skript-Pfad. ASA 1 zeiht sich diesen Pfad direkt von der Amazon API und fügt diesen direkt in die Templates ein, weshalb ein „Voranstellen“ des Pfades zum Skript hier nicht funktioniert.

            Die einzelnen URLs der Bilder werden dann einfach mit dem „.“ Operator verknüpft.

            Ich hoffe dies war einigermaßen verständlich.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Ich akzeptiere die Datenschutzhinweise.