Wie zeige ich geschützte Amazon S3-Bilder auf meiner sicheren Website mit PHP an?

Lesezeit: 7 Minuten

Ich versuche, Bilder für meine Website von meinem Host zum Amazon S3-Cloud-Hosting zu verschieben. Diese Bilder stammen von Kundenarbeitsplätzen und können nicht öffentlich zugänglich sein. Ich möchte, dass sie auf meiner Website angezeigt werden, vorzugsweise mit dem bei Amazon erhältlichen PHP-SDK.

Bisher konnte ich die Konvertierung so skripten, dass ich Datensätze in meiner Datenbank nachschlage, den Dateipfad hole, ihn entsprechend benenne und an Amazon sende.

    //upload to s3
$s3->create_object($bucket, $folder.$file_name_new, array(
    'fileUpload' => $file_temp,
    'acl' => AmazonS3::ACL_PRIVATE, //access denied, grantee only own
    //'acl' => AmazonS3::ACL_PUBLIC, //image displayed
    //'acl' => AmazonS3::ACL_OPEN, //image displayed, grantee everyone has open permission
    //'acl' => AmazonS3::ACL_AUTH_READ, //image not displayed, grantee auth users has open permissions
    //'acl' => AmazonS3::ACL_OWNER_READ, //image not displayed, grantee only ryan
    //'acl' => AmazonS3::ACL_OWNER_FULL_CONTROL, //image not displayed, grantee only ryan
    'storage' => AmazonS3::STORAGE_REDUCED
    )
    );

Bevor ich alles rüber kopiere, habe ich ein einfaches Formular erstellt, um das Hochladen und Anzeigen des Bildes zu testen. Wenn ich ein Bild mit ACL_PRIVATE hochlade, kann ich entweder die öffentliche URL abrufen und habe keinen Zugriff, oder ich kann die öffentliche URL mit einem temporären Schlüssel abrufen und das Bild anzeigen.

<?php
//display the image link
$temp_link = $s3->get_object_url($bucket, $folder.$file_name_new, '1 minute');
?>
<a href="https://stackoverflow.com/questions/5172630/<?php echo $temp_link; ?>"><?php echo $temp_link; ?></a><br />
<img src="https://stackoverflow.com/questions/5172630/<?php echo $temp_link; ?>" alt="finding image" /><br />

Wie funktioniert mein Caching mit dieser Methode? Ich vermute, jedes Mal, wenn ich die Seite aktualisiere oder einen meiner Datensätze ändere, werde ich dieses Bild erneut abrufen und meine Get-Anforderungen erhöhen.

Ich habe auch überlegt, Bucket-Richtlinien zu verwenden, um nur den Bildabruf von bestimmten Referrern zuzulassen. Verstehe ich richtig, dass Amazon nur Anfragen von Seiten oder Domains abrufen soll, die ich angebe?

Ich verwies auf:
https://forums.aws.amazon.com/thread.jspa?messageID=188183&#188183 um das einzurichten, bin dann aber verwirrt, welche Sicherheit ich für meine Objekte benötige. Es schien, als würden sie immer noch nicht angezeigt, wenn ich sie privat gemacht hätte, es sei denn, ich habe den temporären Link wie zuvor erwähnt verwendet. Wenn ich sie öffentlich machte, konnte ich unabhängig vom Referrer direkt zu ihnen navigieren.

Bin ich weit weg von dem, was ich hier versuche? Wird dies nicht wirklich von S3 unterstützt oder übersehe ich etwas Einfaches? Ich habe die SDK-Dokumentation durchgesehen und viel gesucht und bin der Meinung, dass dies etwas klarer dokumentiert sein sollte. Hoffentlich kann jeder Beitrag hier anderen in dieser Situation helfen. Ich habe andere gelesen, die die Datei mit einer eindeutigen ID benennen und Sicherheit durch Unklarheit schaffen, aber das wird in meiner Situation nicht ausreichen und wahrscheinlich keine bewährte Methode für jeden, der versucht, sicher zu sein.

Der beste Weg, Ihre Bilder bereitzustellen, besteht darin, eine URL mit dem PHP-SDK zu generieren. Auf diese Weise gelangen die Downloads direkt von S3 zu Ihren Benutzern.

Sie müssen nicht wie von @mfonda vorgeschlagen über Ihre Server herunterladen – Sie können beliebige Caching-Header für S3-Objekte festlegen – und wenn Sie dies tun würden, würden Sie einige wichtige Vorteile der Verwendung von S3 verlieren.

Wie Sie jedoch in Ihrer Frage angemerkt haben, ändert sich die URL immer (eigentlich die Abfragezeichenfolge), sodass Browser die Datei nicht zwischenspeichern. Die einfache Problemumgehung besteht darin, immer dasselbe Ablaufdatum zu verwenden, sodass immer dieselbe Abfragezeichenfolge generiert wird. Oder noch besser, die URL selbst zwischenspeichern (zB in der Datenbank) und jedes Mal wiederverwenden.

Sie müssen die Ablaufzeit natürlich weit in die Zukunft legen, aber Sie können diese URLs von Zeit zu Zeit neu generieren, wenn Sie dies bevorzugen. zB würden Sie in Ihrer Datenbank die generierte URL und das Ablaufdatum speichern (Sie könnten das auch aus der URL parsen). Dann verwenden Sie entweder einfach die vorhandene URL oder, wenn das Ablaufdatum abgelaufen ist, generieren Sie eine neue. etc…

  • Ich habe heute keine Stimmen mehr, aber das ist richtig. Das Herunterladen der Bilder selbst wäre tatsächlich langsamer, als sie nur selbst zu hosten, wodurch der Vorteil des externen Hostings auf S3 weggeworfen würde.

    – Konerak

    3. März 2011 um 14:26 Uhr

  • Das macht absolut Sinn, scheint aber ein komplizierteres Modell der Sicherheit durch Obskurität zu sein. Ich könnte genauso gut dran sein, S3 nicht zu verwenden und eine .htaccess-Datei zu verwenden, um Hotlinking zu deaktivieren, und eine Proxy-Datei zu verwenden, um mein Bild anzuzeigen, fast wie von @mfonda vorgeschlagen, nur lokal. Also kann ich mit dem SDK die Datei nicht einfach basierend auf den Authentifizierungswerten abrufen, die ich in config.inc.php festgelegt habe? Ich glaube, ich verstehe nicht wirklich, wie man eine Datei als authentifizierter Benutzer abruft. Irgendwelche Eingaben zu Bucket-Richtlinien, damit die Bilder öffentlich sind, aber nur für von mir definierte Referrer verfügbar sind? Das schien nicht zu funktionieren.

    – Bob

    4. März 2011 um 15:53 ​​Uhr

  • @Bob – Es ist viel sicherer als das. Die URL kann nur erstellt werden, wenn die Person Ihren geheimen Schlüssel hat. Natürlich könnte es einfacher sein, die Dateien aus dem lokalen Speicher zu servern, aber dann verlieren Sie alle Vorteile von S3 – nur durch Ihre Kreditkarte begrenzte Kapazität, enorme Bandbreite und Skalierbarkeit usw. Sie können Ihre eigenen Zugriffsrichtlinien erstellen. Sehen docs.amazonwebservices.com/AmazonS3/latest/dev/…aber das ist noch komplizierter und ich bin mir nicht sicher, ob es sowieso das tut, was Sie wollen.

    – Geoff Appleford

    4. März 2011 um 16:33 Uhr

  • Okay, die Vorteile für die Verwendung von S3 sind definitiv enorm. Ich habe noch ein paar Dinge mit Bucket-Richtlinien gemacht und diesen Artikel gefunden http://blog.cloudberrylab.com/2010/07/how-to-prevent-hotlinking-of-your.html Ich muss etwas falsch konfiguriert haben, da dies jetzt zu funktionieren scheint. Die Bilder werden auf meiner Website angezeigt, natürlich blitzschnell, und wenn ich auf „Bild in neuem Tab öffnen“ klicke, erhalte ich die Meldung „Zugriff verweigert“. Kann dieser Referrer dann von jemandem gespooft werden?

    – Bob

    4. März 2011 um 17:27 Uhr


  • @Bob – der Referrer ist nur ein http-Header, sodass er leicht gefälscht werden kann. Es gibt sogar Firefox-Erweiterungen, die das für Sie erledigen. Die Verwendung der Referrer-Bucket-Richtlinie ist großartig, um den Gelegenheitsbenutzer zu stoppen, aber es wird einen entschlossenen und sachkundigen Benutzer nicht stoppen. Aber trotzdem netter Link. Ich kann Bucket-Richtlinien für Ressourcen verwenden, bei denen absolute Sicherheit nicht erforderlich ist.

    – Geoff Appleford

    5. März 2011 um 9:31 Uhr

Sie können Bucket-Richtlinien in Ihrem Amazon-Bucket verwenden, um der Domäne Ihrer Anwendung den Zugriff auf die Datei zu ermöglichen. Sie können sogar Ihre lokale Entwicklerdomäne (z. B. mylocaldomain.local) zur Zugriffsliste hinzufügen und Ihre Bilder abrufen. Amazon stellt hier Muster-Bucket-Richtlinien bereit: http://docs.aws.amazon.com/AmazonS3/latest/dev/AccessPolicyLanguage_UseCases_s3_a.html. Dies war sehr hilfreich, um mir zu helfen, meine Bilder bereitzustellen.

Die folgende Richtlinie hat das Problem gelöst, das mich zu diesem SO-Thema geführt hat:

    {
       "Version":"2008-10-17",
       "Id":"http referer policy example",
       "Statement":[
    {
      "Sid":"Allow get requests originated from www.example.com and example.com",
      "Effect":"Allow",
      "Principal":"*",
      "Action":"s3:GetObject",
      "Resource":"arn:aws:s3:::examplebucket/*",
      "Condition":{
        "StringLike":{
          "aws:Referer":[
            "http://www.example.com/*",
            "http://example.com/*"
          ]
        }
      }
    }
  ]
}

Wenn Sie über Sicherheit und den Schutz von Daten vor unbefugten Benutzern sprechen, ist eines klar: Sie müssen bei jedem Zugriff auf die Ressource, für die Sie berechtigt sind, überprüfen.

Das bedeutet, dass das Generieren einer URL, auf die jeder zugreifen kann (möglicherweise schwierig zu bekommen, aber dennoch …). Die einzige Lösung ist ein Bild-Proxy. Sie können das mit einem PHP-Skript tun.

Es gibt einen schönen Artikel aus dem Blog von Amazon, der die Verwendung von readfile vorschlägt, http://blogs.aws.amazon.com/php/post/Tx2C4WJBMSMW68A/Streaming-Amazon-S3-Objects-From-a-Web-Server

readfile('s3://my-bucket/my-images/php.gif');

  • Link ist 404 atm ^

    – Löwe

    2. Dezember 2021 um 10:44 Uhr

Sie können die Inhalte von S3 (in einem PHP-Skript) herunterladen und sie dann mit den richtigen Headern bereitstellen.

Nehmen wir als grobes Beispiel an, Sie hätten Folgendes drin image.php:

$s3 = new AmazonS3();
$response = $s3->get_object($bucket, $image_name);
if (!$response->isOK()) {
    throw new Exception('Error downloading file from S3');
}
header("Content-Type: image/jpeg");
header("Content-Length: " . strlen($response->body));
die($response->body);

Dann können Sie in Ihrem HTML-Code tun

<img src="https://stackoverflow.com/questions/5172630/image.php">

1083380cookie-checkWie zeige ich geschützte Amazon S3-Bilder auf meiner sicheren Website mit PHP an?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy