본문 바로가기
PHP

[PHP] AWS S3 업로드/다운로드

by noddu 2023. 10. 17.
728x90
반응형

 

AWS 설정

 

AWS SDK 설치

composer require aws/aws-sdk-php

 

 

composer.json, composer.lock 파일과 함께 종속성이 설치됩니다.

 

 

AccessKey, SecretKey 얻기

IAM 대시보드에서 "사용자"를 선택하고 "사용자 생성" 버튼을 클릭하여 새 IAM 사용자를 생성합니다

 

 

권한 정책 중에 AmazonS3FullAccess를 검색해서 선택하고 다음 버튼을 누릅니다.

 

액세스 키를 다운로드 받으면

csv파일로 Access key ID와 Secret access key가 들어있습니다.

 

이 두 키를 가지고 업로드와 다운로드를 해보겠습니다.

 

 

 

반응형

 

 

업로드

 

form.php

<form action="./update.php" method="post">
	...
	<input type="file" name="it_1" id="it_1">
	...
</form>

input에 업로드할 파일을 넣습니다

 

 

 

update.php

// AWS SDK 로드
require("./../../vendor/autoload.php");

use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;

// AWS S3 설정
$bucketName = 'your-bucketName';
$accessKey = 'accessKey';
$secretKey = 'secretKey';
$region = 'yout-region';

// S3 클라이언트 생성
$s3 = new S3Client([
    'version' => 'latest',
    'region' => $region,
    'credentials' => [
        'key' => $accessKey,
        'secret' => $secretKey,
    ],
]);


if ($_FILES['it_1']['tmp_name']) {
    try {
        // S3 버킷에 파일 업로드
        $result = $s3->putObject([
            'Bucket' => $bucketName,
            'Key' => basename($_FILES['it_1']['name']), // S3에 저장될 경로
            'SourceFile' => $_FILES['it_1']['tmp_name'],
            'ACL' => 'private',	// 권한
            'ContentType'=>$_FILES['it_1']['type']
        ]);
    
        // 업로드 성공 시 S3 URL을 저장
        $it_1 = $result['ObjectURL'];
    
    } catch (S3Exception $e) {
        // 업로드 실패 시 에러 처리
        echo "Error uploading file: " . $e->getMessage();
    }
}

업로드에 성공하면 S3의 정한 버킷으로 업로드된 걸 확인할 수 있습니다.

파일을 업로드할 때 권한을 'ACL' => 'private'로 설정합니다.

 

 

ACL을 private로 설정했기 때문에 객체 소유자만 읽기, 쓰기가 가능한 걸 볼 수 있습니다.

 

 

 

update.php

$result = $s3->putObject([
    'ACL' => 'public-read'	// 권한
]);

이렇게 public read로 권한을 설정하고 업로드를 하면

 

 

 

퍼블릭으로 읽기가 가능해진 것을 볼 수 있습니다.

 

 

 

퍼블릭으로 읽기가 가능하면 객체 URL만 있으면 접근이 가능해서 URL이 노출되면

누구든지 접근할 수 있습니다.

 

 

 

수동으로 퍼블릭으로 바꾸려면 이런 알림 창이 뜨지만 문제는 없습니다.

하지만 저는 ACL을 private로 해서 객체 URL로 파일에 접근하는 것을 막고

다운로드할 때 권한을 부여해서 접근하도록 하겠습니다.

 

 

객체 URL로 접근했을 때 이렇게 AccessDenied가 나오면 private로 설정된 것입니다.

 

 

다운로드

 

download.php

// AWS SDK 로드
require("./../../vendor/autoload.php");

use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;

// AWS S3 설정
$bucketName = 'your-bucketName';
$accessKey = 'accessKey';
$secretKey = 'secretKey';
$region = 'yout-region';

// S3 클라이언트 생성
$s3 = new S3Client([
    'version' => 'latest',
    'region' => $region,
    'credentials' => [
        'key' => $accessKey,
        'secret' => $secretKey,
    ],
]);


try {
    // 서명된 URL 생성
    $command = $s3->getCommand('GetObject', [
        'Bucket' => $bucketName,
        'Key' => $it["it_1_file"],    // 다운로드할 객체(파일 경로)
    ]);
    
    // 10분동안 유효한 서명된 URL을 얻는다.(유효 기간 설정)
    $signedUrl = $s3->createPresignedRequest($command, '+10 minutes')->getUri(); // +1 hour 이런식으로도 가능
    header("location: {$signedUrl}");	// URL이동 (바로 다운받기)
} catch (S3Exception $e) {	// 에러 처리
    echo "Error: " . $e->getMessage();
}

다운로드할 때는 객체의 유효한 객체 URL을 새로 얻습니다.

URL은 설정한 시간만큼 유효하고,

header(location: URL)으로 바로 URL로 이동하면서 해당 객체를 다운로드할 수 있습니다.

 

 

download.php

// S3에 업로드하는 함수
function uploadS3($s3, $bucketName, $file) {
    try {
        $result = $s3->putObject([
            'Bucket' => $bucketName,
            'Key' => basename($file['name']),
            'SourceFile' => $file['tmp_name'],
            'ACL' => 'private',
            'ContentType' => $file['type']
        ]);
        return $result['ObjectURL'];
    } catch (S3Exception $e) {
        error_log("Error uploading file: " . $e->getMessage());
        return null;
    }
}


if ($_FILES['it_1']['tmp_name']) {
    $it_1 = uploadS3($s3, $bucketName, $_FILES['it_1']);
    if ($it_1) {
        $it_1_subj = $_FILES['it_1']['name'];
    }
}

다음에 또 사용하기 위해 업로드하는 함수를 만들었습니다!

반응형

'PHP' 카테고리의 다른 글

Docusign SDK (JWT Grant인증)전자 서명  (0) 2023.09.19
PHP 짧은 태그 에러 (소스코드가 보여짐)  (0) 2023.04.03