AWS SDK for PHP 버전 3을 사용한 Amazon S3의 사전 서명된 URL
HTTP 인증 헤더를 사용하는 대신 쿼리 문자열 파라미터로 필요한 정보를 전달하여 특정 유형의 요청을 인증할 수 있습니다. 이 방법은 요청을 프록시하지 않고 타사 브라우저에서 Amazon S3 비공개 데이터에 직접 액세스할 수 있도록 할 경우에 유용합니다. 핵심은 "미리 서명된" 요청을 구성하여 다른 사용자가 사용할 수 있는 URL로 인코딩하는 것입니다. 또한 만료 시간을 지정하여 미리 서명된 요청을 제한할 수 있습니다.
HTTP GET 요청에 대해 미리 서명된 URL 생성
다음 코드 예시는 SDK for PHP를 사용하여 HTTP GET 요청에 대해 미리 서명된 URL을 생성하는 방법을 보여줍니다.
<?php require 'vendor/autoload.php'; use Aws\S3\S3Client; $s3Client = new S3Client([ 'region' => 'us-west-2', ]); // Supply a CommandInterface object and an expires parameter to the `createPresignedRequest` method. $request = $s3Client->createPresignedRequest( $s3Client->getCommand('GetObject', [ 'Bucket' => 'amzn-s3-demo-bucket', 'Key' => 'demo-key', ]), '+1 hour' ); // From the resulting RequestInterface object, you can get the URL. $presignedUrl = (string) $request->getUri(); echo $presignedUrl;
자세한 내용은 createPresignedRequest 메서드에 대한 API 참조에서 확인할 수 있습니다.
다른 사용자는 $presignedUrl 값을 사용하여 향후 1시간 이내에 해당 객체를 가져올 수 있습니다. 예를 들어 브라우저를 통해 HTTP GET 요청이 수행되면 S3 서비스에는 이 호출이 사전 서명된 URL을 생성한 사용자로부터 온 것으로 인식됩니다.
HTTP PUT 요청에 대해 미리 서명된 URL 생성
다음 코드 예시는 SDK for PHP를 사용하여 HTTP PUT 요청에 대해 미리 서명된 URL을 생성하는 방법을 보여줍니다.
<?php require 'vendor/autoload.php'; use Aws\S3\S3Client; $s3Client = new S3Client([ 'region' => 'us-west-2', ]); $request = $s3Client->createPresignedRequest( $s3Client->getCommand('PutObject', [ 'Bucket' => 'amzn-s3-demo-bucket', 'Key' => 'demo-key', ]), '+1 hour' ); // From the resulting RequestInterface object, you can get the URL. $presignedUrl = (string) $request->getUri();
이제 다른 사용자가 미리 서명된 URL을 HTTP PUT 요청에 사용하여 파일을 업로드할 수 있습니다.
use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; // ... function uploadWithPresignedUrl($presignedUrl, $filePath, $s3Client): ?Response { // Get the HTTP handler from the S3 client. $handler = $s3Client->getHandlerList()->resolve(); // Create a stream from the file. $fileStream = new Stream(fopen($filePath, 'r')); // Create the request. $request = new Request( 'PUT', $presignedUrl, [ 'Content-Type' => mime_content_type($filePath), 'Content-Length' => filesize($filePath) ], $fileStream ); // Send the request using the handler. try { $promise = $handler($request, []); $response = $promise->wait(); return $response; } catch (Exception $e) { echo "Error uploading file: " . $e->getMessage() . "\n"; return null; } }