S3 설정
다이렉트 업로드를 구현하기 위해서는 먼저 AWS S3를 적절히 설정해야 합니다.
* AWS 계정 생성: 유효한 이메일과 계정 정보를 제공하여 AWS 계정을 생성합니다.
* S3 버킷 생성: AWS 콘솔에서 S3 서비스로 이동하여 새 버킷을 생성합니다. 다음 설정을 권장합니다:
* 버킷 유형: “General purpose”
* 객체 소유권: ACL 비활성화
* 모든 퍼블릭 액세스 차단: 활성화
* 버킷 버전 관리: 비활성화
* 태그, 암호화, 객체 잠금: 기본값 유지
* 사용자 및 권한 구성: IAM(Identity and Access Management)을 통해 AWS 사용자를 생성하고 AmazonS3FullAccess 정책을 연결합니다. 이후, 접근 키(Access Key ID)와 비밀 접근 키(Secret Access Key)를 생성하여 안전하게 보관해야 합니다. 이 키들은 Rails 애플리케이션에서 S3에 접근하는 데 필수적입니다.
CORS 설정
크로스 오리진 요청을 허용하기 위해 S3 버킷에 CORS(Cross-origin Resource Sharing) 정책을 구성해야 합니다. 이는 사용자 브라우저가 Rails 애플리케이션 도메인에서 S3 버킷으로 직접 요청을 보낼 수 있도록 허용하기 위함입니다.
* 버킷의 Permissions 페이지에서 CORS 설정을 추가합니다.
* AllowedHeaders: Content-Type, Content-Md5, Content-Disposition
* AllowedMethods: POST, PUT
* AllowedOrigins: http://localhost:3000, https://avohq.io 등 (애플리케이션 도메인)
* MaxAgeSeconds: 3600
* 주의: AllowedOrigins를 *로 설정할 경우 보안 위험이 있으므로, 명시적으로 신뢰하는 도메인만 추가해야 합니다.
애플리케이션 설정
Rails 애플리케이션에 Active Storage 다이렉트 업로드를 통합하는 단계는 다음과 같습니다.
* Rails 앱 생성 및 Active Storage 설치: rails new 명령으로 새 앱을 만들고 bin/rails active_storage:install로 Active Storage를 설치합니다.
* 모델 설정: Post 모델을 생성하고 has_one_attached :cover를 추가하여 파일 첨부를 활성화합니다.
* Gemfile 업데이트: aws-sdk-s3와 image_processing 젬을 추가하고 bundle install을 실행합니다.
* JavaScript 설정: @rails/activestorage를 importmap pin하고 application.js에 ActiveStorage.start()를 추가합니다.
* 컨트롤러 파라미터: PostsController의 post_params에 :cover를 추가하여 파일 첨부를 허용합니다.
Rails 다이렉트 업로드 구현
- S3 서비스 구성:
config/credentials.yml.enc에 AWS 접근 키, 비밀 키, 리전, 버킷 정보를 안전하게 저장합니다. config/storage.yml업데이트:amazon서비스를 S3로 설정하고, 자격 증명에서 AWS 정보를 가져오도록 구성합니다.- 환경 설정:
config/environments/development.rb에서config.active_storage.service = :amazon으로 설정하여 Active Storage가 S3 서비스를 사용하도록 지정합니다. - 파일 입력 필드에
direct_upload: true추가: 폼에form.file_field :cover, direct_upload: true를 추가하여 기본 다이렉트 업로드를 활성화합니다.
Stimulus를 이용한 사용자 경험 개선
기본 다이렉트 업로드는 폼 제출 시 작동하지만, 사용자에게 피드백이 부족합니다. Stimulus 컨트롤러를 활용하여 이를 개선할 수 있습니다.
* Stimulus 컨트롤러 생성: direct-upload 컨트롤러를 생성하여 파일 선택 시 즉시 업로드하고 진행률 표시줄을 구현합니다.
* DirectUpload 클래스 활용: Active Storage의 DirectUpload 클래스를 사용하여 프로그래밍 방식으로 파일을 업로드합니다.
* 진행률 표시: directUploadWillStoreFileWithXHR 메서드를 통해 XHR 요청에 progress 이벤트 리스너를 추가하여 업로드 진행률을 시각적으로 표시합니다.
* 피드백 제공: 업로드 성공, 실패 시 사용자에게 적절한 메시지를 표시하여 원활한 사용자 경험을 제공합니다.
대체 서비스
Cloudflare R2, Digital Ocean Spaces와 같은 S3 호환 서비스도 유사한 방식으로 설정하여 사용할 수 있습니다. storage.yml에서 endpoint와 자격 증명만 변경하면 됩니다.