기존에는 서버에서 attachments/ 로 저장하던 파일들을.. ec2 디스크 문제로 몇번 터진 이후
개인적으로 꼭 S3로 옮기고 말겠다는 생각을 했는데,
이번에 마이그레이션 진행하면서 그냥 작업해버렸다.
꼭 내가 이 회사 안있더라도, 다른 사람들이 attachments/ 로 고통받을 걸 잘 알기에...
그냥 바로 작업 시작해버림
IAM 계정을 하나 만들어줘야 한다. ci4가 접근할..
생성은 plain하게 진행하고, 생성된 후에 액세스 키를 만들어줘야 한다.
오른쪽 상단의 액세스 키 만들기를 선택해준다.
액세스 키 모범 사례 및 대안에서는 서드 파티 서비스
를 선택해준다.
그리고 나온 두개의 액세스 키를 잘 보관한다.
<?php
namespace Config;
use CodeIgniter\Config\BaseConfig;
class S3 extends BaseConfig
{
public string $bucketName;
public string $region;
public string $accessKey;
public string $secretKey;
public string $uploadFolder;
public function __construct()
{
$this->bucketName = getenv('AWS_S3_BUCKET')?? "image-ci4";
$this->region = getenv('AWS_REGION')?? "ap-northeast-2";
$this->accessKey = getenv('AWS_ACCESS_KEY')?? "-----------------";
$this->secretKey = getenv('AWS_SECRET_KEY')?? "---------------------";
$this->uploadFolder = getenv('AWS_UPLOAD_FOLDER') ?? 'images/';
}
}
이런식으로 config에 선언해주던가,
.env에
환경변수로 선언하던가...
아니면 그냥 S3uploader 파일쪽에 선언해도 상관없다. 아무튼 들어가있으면 됨.
근데 보안적인 측면에서 셋 다 별로고 AWS측에서 제공하는 보안 키 .. 관련된 뭐시기가 있다했느데 그걸 쓰면 더 좋을듯하다.
<?php
namespace App\Libraries;
use Aws\S3\S3Client;
use Config\S3;
class S3Uploader
{
private $s3;
private $bucket;
private $uploadFolder;
public function __construct()
{
$config = new S3();
$this->s3 = new S3Client([
'version' => 'latest',
'region' => 'ap-northeast-2',
'credentials' => [
'key' => "",
'secret' => ""
],
]);
$this->bucket = $config->bucketName;
$this->uploadFolder = $config->uploadFolder;
}
public function uploadFile($file)
{
$sFileName = $file->getRandomName();
try {
$this->s3->putObject([
'Bucket' => $this->bucket,
'Key' => $sFileName,
'Body' => fopen($file->getTempName(), 'rb'),
'ContentType' => $file->getMimeType()
]);
return "https://{$this->bucket}.s3.{$this->s3->getRegion()}.amazonaws.com/{$sFileName}";
} catch (\Exception $e) {
return $e->getMessage();
}
}
}
여러모로 중구난방인데 아무튼 , config에서 bucketName 불러오듯 key 값도 불러오면 된다 .. (난 한 1시간정도밖에 없어서.. 후딱 만드느라 막 함 추후 수정해야지)
위의 코드를 보면, return 값으로 url을 주고 있음.
이걸 RDB에 저장하고, RDB에서는 이 값을 이용해 이미지를 호출하게 됨.
$aImages = $this->request->getFileMultiple('document_images');
$oS3 = new S3Uploader();
foreach($aImages as $oImage){
if($oImage->isValid() && !$oImage->hasMoved()){
$sUrl = $oS3->uploadFile($oImage);
if ($sUrl) {
$aUpload[] = $sUrl;
// DB 적재
$aData = [
//"title" => $oImage->getName(),
"box_idx" => $iBox,
"file_path" => $sUrl
];
if($this->oMypage->insertBox($aData)){
$aSuccess[] = $sUrl;
}else {
$aFailure[] = $sUrl;
}
} else {
$aFailure[] = $sUrl;
}
}
}
난 로그 쌓을거라 이렇게 Failure 등 따로 append 했다!!!
연동할 때 고민해줘야 하는 부분이 있는데, 바로 어디까지 public으로 접근 가능하게 할 지에 대한 부분이다.
S3 자체를 public 으로 하는 방법도 있지만 절-대 추천하지 않고,
나는 일부 소스 (일부 경로)에 대해서만 public 권한을 주고 나머지는 private으로 유지하는 방법을 선택했다.
Library 코드에는 나와있지 않지만 경로가 설정되어 있고, 해당 경로로 public 권한을 open해주는 설정을 json으로 선택할 수 있다.
버킷 권한의 버킷 정책이다.
여기에서 특정 경로의 public 권한 관련된 내용은 찾아보기를..