4. Dynamisches einbinden per PHP Script
Diese Methode stellt nicht nur sicher das ein Besucher die Bilder von unserer Seite aufruft, sondern es wird auch noch der eigentliche Ablageort verborgen, damit kein Massendownload stattfinden kann. Um die Bilder vor Hotlinking zu schützen müssen wir sowohl die eigentliche Webseite um einige Zeilen erweitern, als auch ein entsprechendes Script basteln das die Bilder ausliefert.
Zunächst die eigentliche Seite in gekürzter Fassung (Doctype und Teile des Head wurden hier entfernt)
HTML-Code:
<?php
session_start();
$_SESSION['bilder_erlaubt'] = 1;
?>
<html>
<head>
<title>Trafficklau- Nein Danke!</title>
</head>
<body>
<img src="img.php?src=huebsches_bild.jpg" />
</body>
</html>
Als erstes wird eine Session gestartet und danach ein Wert gesetzt an dem wir erkennen das ein Besucher berechtigt ist ein Bild anzuschauen. Dies geschieht mit den Zeilen
PHP-Code:
session_start();
$_SESSION['bilder_erlaubt'] = 1;
Diese Zeilen sind sehr wichtig, denn der ganze Schutz basiert auf PHP Sessions. Deswegen muß auf jeder Seite als erstes ein session_start() plaziert werden, damit wir unterwegs nicht die Information verlieren ob ein Besucher berechtigt ist unsere Bilder zu sehen.
Code:
<img src="img.php?src=huebsches_bild.jpg" />
Im IMG-Tag geben wir nun statt des einfachen Bildes den Scriptname an, an das der Name des anzuzeigenden Bildes übergeben wird. Alle weiteren Schritte passieren im PHP-Teil. Nachfolgend der Inhalt von unserer img.php
PHP-Code:
<?php
session_start();
if (isset( $_GET['src'] ))
{
$datei = explode( ".", $_GET['src'] );
$datei = array_reverse( $datei );
if ($datei[0] == "jpg" &&
file_exists( $_GET['src'] ) &&
$_SESSION['bilder_erlaubt'] == 1 )
{
header( 'Content-type: image/jpeg' );
echo file_get_contents( $_GET['src'] );
}
else
{
header( 'Content-type: image/gif' );
echo file_get_contents( 'logo.gif' );
}
}
?>
Zunächst wird wieder die Session gestartet, um die darin abgelegten Informationen zu erhalten. Als nächstes wird geprüft ob das Script mit einer Bild-Anforderung aufgerufen wurde: if (isset( $_GET['src'] ))
Ist das der Fall wird zunächst mit
PHP-Code:
$datei = explode( ".", $_GET['src'] );
$datei = array_reverse( $datei );
der übergebene Dateiname zerlegt. Getrennt wird am Punkt im Dateiname, womit wir den Name und die Endung separieren und in einem Array ablegen. Anschliessend drehen wir das Array um, so das der letzte Eintrag an erster Stelle steht. Im Optimalfall ist das unsere Dateiendung. Ich habe diesen Weg gewählt, da so Dateinamen mit mehreren Punkten im Namen nicht zu Fehler führen.
PHP-Code:
if ($datei[0] == "jpg" &&
file_exists( $_GET['src'] ) &&
$_SESSION['bilder_erlaubt'] == 1 )
Mit diesen Zeilen werden verschiedene Sachen geprüft, nämlich ob- Der übergebene Dateiname auf jpg endet und somit ein Bild ist.
- Die Datei auf unserem Server existiert
- Der Benutzer berechtigt ist das angeforderte Bild zu sehen
Treffen alle Kriterien zu, dann
PHP-Code:
header( 'Content-type: image/jpeg' );
echo file_get_contents( $_GET['src'] );
senden wir einen Header in dem mitgeteilt wird das die Scriptantwort ein JPG ist. Anschliessend lesen wir die Datei ein und senden sie mit echo an den Browser.
Traf ein Kriterium nicht zu, so ist der Benutzer nicht berechtigt das Bild zu sehen und deswegen geben wir mit
PHP-Code:
header( 'Content-type: image/gif' );
echo file_get_contents( 'kein_zugriff.gif' );
eine Alternativ-Grafik aus. Dadurch wird verhindert das jemand einfach von extern oder direkt das Script mit einem Bild-Parameter aufruft.
Anzumerken ist noch, daß in den Anweisungen
PHP-Code:
echo file_get_contents( '...' );
an Stelle des "..." zusätzlich zum Dateinamen noch ein Pfad auf dem Server zum Bild angegeben werden kann der nur dem Site-Betreiber bekannt ist. Dieser Pfad wird nicht öffentlich angezeigt und somit kann man den tatsächlichen Ablageort verschleiern und niemand kann die Bild-Datei direkt aus dem Ordner kopieren.
Achtung: Wenn ein Pfad zu einem Ordner angegeben wird, muß dieser auch in der Zeile
PHP-Code:
file_exists( $_GET['src'] )
angegeben werden, da es hier sonst zu einem Fehler kommt und die Alternativ-Grafik ausgegeben wird!
5. Mit PHP dem Bild ein Wasserzeichen hinzufügen
Als 5. und letzte Möglichkeit wollen wir uns ansehen, wie wir dynamisch mit wenigen Zeilen Code ein Wasserzeichen auf unsere Bilder bekommen. Wie im 4. Beispiel wird auch in diesem Beispiel mit 2 Dateien gearbeitet. Der HTML-Teil ist fast identisch mit dem vorherigen Script, nur das wir hier keine Session benötigen.
HTML-Code:
<html>
<head>
<title>Trafficklau- Nein Danke!</title>
</head>
<body>
<img src="img.php?src=huebsches_bild.jpg" />
</body>
</html>
Erklärungen spare ich mir hier, weil nichts neues dazu kam. Das PHP-Script unterscheidet sich aber erheblich vom vorherigen und sieht wie folgt aus:
PHP-Code:
<?php
header( 'Content-type: image/jpeg' );
$wasserzeichentext = "Copyright by www.domain.tld";
if (isset( $_GET['src'] ))
{
$datei = explode( ".", $_GET['src'] );
$datei = array_reverse( $datei );
if ($datei[0] == "jpg")
{
$image = imagecreatefromjpeg( $_GET['src'] );
$TextFarbe = imagecolorallocate ( $image, 255, 128, 0 );
imagettftext ( $image, 28, 45, 320, 475, $TextFarbe, "verdana.ttf", $wasserzeichentext );
imagejpeg( $image, "", 97 );
imagedestroy( $image );
}
}
?>
Die erste Zeile kennen wir bereits. Hier wird ein Header gesendet damit korrekterweise ein JPG ausgegeben wird. In der zweiten Zeile wird der Text festgelegt der über das Bild gelegt werden soll. Nachdem geprüft wurde ob und das ein JPG angefordert wurde (Erklärung siehe 4.), beginnt das eigentlich Script.
PHP-Code:
$image = imagecreatefromjpeg( $_GET['src'] );
Erzeugt vom angeforderten Bild eine neue Grafik. Anschliessend legen wir mit
PHP-Code:
$TextFarbe = imagecolorallocate ( $image, 255, 128, 0 );
die Textfarbe für das Wasserzeichen fest. In diesem Beispiel hätte die Textfarbe einen Orange-Ton.
PHP-Code:
imagettftext ( $image, 28, 45, 320, 475, $TextFarbe, "gilligan.ttf", $wasserzeichentext );
imagejpeg( $image, "", 97 );
imagedestroy( $image );
Hier geschieht die Zusammenführung von Wasserzeichen und Bild, bevor das Bild an den Browser gesendet wird und abschließend werden die belegten Resourcen wieder freigegeben. Eine detaillierte Erklärung möchte ich mir an dieser Stelle sparen und verweise auf das CAPTCHA Tutorial, das diese Technik ebenfalls anwendet. Alle eingesetzten Befehle werden dort sehr ausführlich erklärt.
Wer statt eines Textes lieber ein Bild als Wasserzeichen benutzen möchte, dem lege ich die Wasserzeichen-Funktion im Traum-Scripts Forum nahe.
Fazit
Wie wir gesehen haben gibt es diverse Wege sich vor Trafficklau und Bilderdieben zu schützen. Auch wenn es die ultimative Lösung nicht gibt, so haben wir doch diverse Mittel uns dagegen zur Wehr zu setzen. Die aufgezeigten PHP-Lösungen sind nur oberflächlicher Natur und bieten noch sehr viel Raum für Verbesserungen und Erweiterungen. Dieser Part bleibt aber jedem selbst überlassen, da es nicht direkt Gegenstand dieses Tutorials ist. Der Fantasie und Experimentierfreude sind hier keine Grenzen gesetzt.
Damit sind wir am Ende angekommen und ich hoffe dieses Tutorial ist dem ein oder anderen von Nutzen.
Tschüß und bis zum nächsten Tutorial