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𭼗 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…
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');
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">
10833800cookie-checkWie zeige ich geschützte Amazon S3-Bilder auf meiner sicheren Website mit PHP an?yes