2011-03-02 3 views
23

내 사이트의 이미지를 내 호스트에서 Amazon S3 클라우드 호스팅으로 이동하려고합니다. 이 이미지는 클라이언트 작업 사이트의 것이며 공개적으로 사용할 수 없습니다. Amazon에서 제공하는 PHP SDK를 사용하여 선호하는 사이트에 내 사이트를 표시하고 싶습니다.PHP를 사용하여 보안 사이트에 보호 된 Amazon S3 이미지를 표시하려면 어떻게합니까?

지금까지 나는 데이터베이스에서 레코드를 검색하고 파일 경로를 잡고 적절하게 이름을 지정하여 Amazon으로 보낼 수 있도록 변환 스크립트를 작성했습니다.

//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 
    ) 
    ); 

모든 것을 복사하기 전에 이미지 업로드 및 표시 테스트를 수행하기위한 간단한 양식을 만들었습니다. ACL_PRIVATE를 사용하여 이미지를 업로드하면 공개 URL을 가져올 수 있으며 액세스 권한이 없거나 임시 URL로 공개 URL을 가져 와서 이미지를 표시 할 수 있습니다.

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

내 캐싱은 어떻게 작동합니까? 페이지를 새로 고칠 때마다 또는 내 기록 중 하나를 수정할 때마다 추측하고 있습니다. 이미지를 다시 가져 와서 내 요청을 늘릴 것입니다.

특정 참조 자의 이미지 검색 만 허용하기 위해 버킷 정책을 사용하는 것도 고려했습니다. Amazon이 내가 지정한 페이지 또는 도메인의 요청 만 가져 오기로되어 있음을 올바르게 알고 있습니까?

참조 : https://forums.aws.amazon.com/thread.jspa?messageID=188183&#188183이 내용을 설정했지만 내 개체에 어떤 보안이 필요한지 혼란 스럽습니다. 이전에 언급 한 것과 같이 임시 링크를 사용하지 않았다면 내가 비공개로 설정해도 여전히 표시되지 않는 것처럼 보였습니다. 공개 한 경우 리퍼러에 관계없이 직접 탐색 할 수 있습니다.

여기에서 내가 뭘하려는거야? 이것은 S3에서 실제로 지원되지 않습니까? 아니면 간단한 것을 놓치고 있습니까? 나는 SDK 문서를 통해 많은 검색과 느낌을 보였으므로 조금 더 명확하게 문서화되어야한다. 그래서 여기에있는 모든 입력이이 상황에서 다른 사람들을 도울 수있다. 필자는 고유 한 ID로 파일의 이름을 지정하고 모호하게 보안을 설정하는 사람을 읽었지만 내 상황에서는이를 잘라 내지 않으며 보안을 유지하려는 사람에게는 모범 사례가 아닐 수도 있습니다.

답변

23

가장 좋은 방법을 수행 할 수 있습니다 생성 할 수있다 : 거친 예를 들어

, 당신은 image.php에 다음했다 말할 PHP SDK를 사용하는 URL. 그렇게하면 다운로드가 S3에서 사용자로 직접 이동합니다.

@mfonda가 제안한대로 서버를 통해 다운로드 할 필요가 없습니다. S3 객체에서 원하는 캐싱 헤더를 설정할 수 있습니다. 그렇게했다면 S3를 사용하면 몇 가지 주요 이점을 잃게됩니다.

그러나 질문에서 지적했듯이 브라우저가 파일을 캐시하지 않도록 URL이 항상 변경됩니다 (실제로는 쿼리 문자열). 쉬운 해결 방법은 동일한 쿼리 문자열이 항상 생성되도록 항상 동일한 만료 날짜를 사용하는 것입니다. 또는 더 나은 여전히 ​​'캐시'URL을 자신 (예 : 데이터베이스) 및 매번 그것을 재사용.

당신은 분명히 만료 시간을 미래의 어딘가에 설정해야하지만, 원한다면이 URL을 너무 자주 재생성 할 수 있습니다. 예를 들어 데이터베이스에서 생성 된 url과 만료일을 저장할 것입니다 (url에서 파싱 할 수도 있습니다). 그런 다음 기존 URL을 사용하거나 만료 날짜가 지난 경우 새 URL을 생성하십시오. 등등 ...

+0

입니다, 그러나 이것은 올바른 것입니다. 이미지를 직접 다운로드하는 것은 실제로 자신을 호스팅하는 것보다 느려지므로 S3에서 외부 호스팅의 장점을 버리게됩니다. – Konerak

+0

이것은 완벽한 의미를 지니지 만, 모호한 모델을 통해 더욱 복잡한 보안처럼 보입니다. S3를 사용하지 않고 .htaccess 파일을 사용하여 hotlink를 비활성화하고 프록시 파일을 사용하여 @mfonda가 제안한 것과 거의 흡사하게 내 이미지를 표시 할 수 있습니다. SDK를 사용하면 config.inc.php에서 설정 한 인증 값을 기반으로 파일을 가져올 수 없습니다. 나는 인증 된 사용자로서 파일을 잡는 방법을 정말로 이해하지 못하고 있다고 생각한다. 버킷 정책에 대한 모든 입력으로 이미지가 공개되지만 내가 정의한 리퍼러 만 사용할 수 있습니까? 그게 효과가없는 것 같아요. – Bob

+0

@Bob - 그보다 훨씬 안전합니다. 그 사람이 귀하의 비밀 키를 가지고 있지 않으면 URL을 생성 할 수 없습니다. 물론 로컬 저장소에서 파일을 서버하는 것이 더 간단 할 수도 있지만 S3의 모든 이점을 잃게됩니다. 용량은 신용 카드, 거대한 대역폭 및 확장성에 의해서만 제한됩니다. 자체 액세스 정책을 만들 수 있습니다. http://docs.amazonwebservices.com/AmazonS3/latest/dev/index.html?AccessPolicyLanguage.html을 참조하십시오.하지만 더 복잡하고 어쨌든 원하는대로 할 수 있을지 확신하지 못합니다. –

0

콘텐츠를 S3 (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); 

그런 다음 HTML 코드에서, 당신은 당신의 이미지를 제공하기 위해

<img src="image.php"> 
6

Amazon 버켓의 버킷 정책을 사용하면 애플리케이션의 도메인에서 파일에 액세스 할 수 있습니다. 사실, 당신은 심지어 당신의 로컬 dev 도메인 (예 : mylocaldomain.local)을 액세스리스트에 추가 할 수 있고 당신은 당신의 이미지를 얻을 수있을 것입니다. Amazon은 여기 샘플 물통 정책을 제공합니다 : http://docs.aws.amazon.com/AmazonS3/latest/dev/AccessPolicyLanguage_UseCases_s3_a.html. 이는 내 이미지를 제공하는 데 큰 도움이되었습니다.

{ 
     "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/*" 
      ] 
     } 
     } 
    } 
    ] 
} 
2

보안 및 인증되지 않은 사용자로부터 보호하는 데이터에 대해 이야기 무언가가 분명하다 : 당신은 당신이 있음에 액세스 할 때마다 확인해야하는 정책은 아래이 SO 주제에 나를 데리고 문제를 해결

리소스를 사용할 수 있습니다.

즉, 누구나 액세스 할 수있는 URL을 생성한다는 것은 (얻기가 어려울 수 있지만 여전히 ...). 유일한 해결책은 이미지 프록시입니다. 당신은 PHP 스크립트로 할 수 있습니다.

가 ReadFile을 사용 sugests 아마존의 블로그에서 좋은 기사, 나는 오늘 투표 나갈거야 http://blogs.aws.amazon.com/php/post/Tx2C4WJBMSMW68A/Streaming-Amazon-S3-Objects-From-a-Web-Server

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

네, 간단합니다. 감사합니다. –