티스토리 뷰
Ruby on Rails : 게시판 텍스트 편집기 (TinyMCE) + AWS S3 이미지 업로드 연동 [Gem : TinyMCE, carrierwave, fog, ...]
나른한 하루 2019. 11. 3. 21:15해당 글은 https://blog.naver.com/kbs4674/221039105137 로 부터 게시글이 이전되었습니다.
드디어.. 오랜 시간 끝에 TinyMCE + AWS S3 을 이용한 이미지 업로드 법을 알아냈습니다..
많은 분들께 도움되라는 의미로 방법을 올리겠습니다.
잠깐, TinyMCE가 뭐에요??
Before...
이번 작업을 하기 전에 앞서, TinyMCE가 기본적으로 깔려있어야 합니다.
- TinyMCE 설치 : https://kbs4674.tistory.com/48
주의
이번 작업은 AWS와 연동되는 작업입니다.
Git 저장소 프로젝트가 Public이신 분은 모두 'Private'으로 전환을 권유 드립니다.
다른 사람이 마음먹고 당신 서버 앞으로 악의적인 자료 업로드를 하게되면 엄청난 서버 요금이 부과될 수 있습니다.
본격적인 TinyMCE에 이미지 업로드 기능 도입에 앞서, 잠시 AWS 기능을 사전에 설정하는 과정을 거치겠습니다.
- 사전 준비 AWS : 보안자격 증명
어떤 보안시설 건물에 입장할려면 카드키를 센서에 대고 들어가듯, AWS 보안자격은 "출입증 카드"를 만든다라고 보면 되겠습니다.
AWS S3 연동전에 앞서 저희는 보안키를 만들어 보는 과정을 거쳐보겠습니다.
1. aws.amazon.com 회원가입을 합니다.
참고
대학 및 단체에 소속되어있으면서, 웹 메일을 가지셨다면 AWS 100달러 프로모션 쿠폰을 가지실 수 있습니다!
- 100달러 지원 단체 보기 : 클릭
2. AWS 회원가입 후
[사진 2-1] 상단 메뉴바에서 'AWS 소개 - 내 보안 자격 증명' 선택
[사진 2-2] 그리고 좌측의 '사용자' 메뉴로 이동 후, '사용자 추가'을 클릭해서 새로운 유저 계정 생성을 합니다.
[사진 2-3] 사용자 이름에 아무거나 쳐주시고, 액세스 유형은 '프로그래밍 방식 엑세스' 선택
[사진 2-4] 권한 설정에서 '기존 정책 직접 연결'를 선택 후, 아래 필터 정책 검색창에 간단히 'S3'를 검색한 후,
'AmazonS3FullAccess'를 체크해 주고 다음:검토 이동.
참고 이 과정은 AWS 보안 등록에 있어 AWS S3에 대해서만 AWS 연동을 허용하겠다는 겁니다.
(키가 털리더라도 최소한의 피해만 입는게 낫겠죠?..)
[사진 2-5] 자신이 설정한게 맞는지 확인한 후,
[사진 2-6] Access key ID와 Secret access key를 다른곳에 적어둡시다. (메모장 등에 복붙)
※ 참고로 엑세스 정보를 까먹거나 잊어버리더라도 다음에 다른 ID와 key를 부여받을 수 있습니다.
(비밀 엑세스 키는 현 시점 때에만 열람 가능)
- 사전 준비 AWS : S3 저장소(Bucket) 설정
1. AWS Credentials user 추가를 마치고, 상위 메뉴에서 'Services'에서 좌측의 S3 탭을 클릭하면 보이는 Storage-S3 로 이동합니다.
2. 새로운 Bucket을 생성합니다.
- Chapter 1 Rails프로젝트와 AWS 연동 작업
1. Gemfile 에 가서 다음을 입력합니다.
gem 'tinymce-rails-imageupload', '~> 4.0.0.beta'
gem 'carrierwave'
gem 'fog', '~> 1.41.0'
참고 fog Gem은 위와같이 특정 버전을 가리켜서 설치해주세요. 최신 버전으로 설치 시 dependency 에러가 발생합니다.
그리고 터미널 명령어창에
bundle install
을 입력해줘서 Gem을 설치해줍니다.
2. 환경변수 설정을 위해 config 폴더에 application.yml 파일을 생성 후, 다음 내용을 입력해주세요.
## config/application.yml
AWS_ACCESS_ID: "xxxxxxxxxx"
AWS_ACCESS_SECRET_KEY: "yyyyyyyyyyy"
AWS_REGION: "ap-northeast-2"
AWS_S3_END_POINT: "https://s3-ap-northeast-2.amazonaws.com"
참고
- AWS_ACCESS_ID 및 AWS_ACESS_SECRET_KEY는 Chapter 1 때 발급받은 본인의 정보를 입력해주세요.
- AWS_REGION 및 AWS_SE_END_POINT는 한국서버 기준으로 작성되었습니다.
3. Github에 해당 프로젝트를 올리게 될 경우, .gitignore 파일 내에 Push를 방지하는 코드를 추가해주세요.
## .gitignore
/config/application.yml
4. config/initializers 폴더 내에 새로운 파일을 생성해 주고, fog.rb 라는 명칭을 붙입니다.
CarrierWave.configure do |config|
config.fog_provider = 'fog/aws' # required
config.fog_credentials = {
provider: 'AWS', # required
aws_access_key_id: "#{ENV["AWS_ACCESS_ID"]}", # required
aws_secret_access_key: "#{ENV["AWS_ACCESS_SECRET_KEY"]}", # required
region: "#{ENV["AWS_REGION"]}", # 아시아-한국서버 명칭
endpoint: "#{ENV["AWS_S3_END_POINT"]}" # 아시아-한국서버
}
config.fog_directory = '아까 자신이 S3에서 만든 bucket 명칭' # required
config.fog_public = true # optional, defaults to true
config.fog_attributes = { } # optional, defaults to {}
# 이미지를 가진 게시글 삭제 시 AWS S3서버에도 자동 삭제처리
config.remove_previously_stored_files_after_update = true
end
5. 터미널에 다음 명령을 입력합니다.
rails g uploader image
그럼 app 폴더 내에 uploaders라는 폴더가 생성된게 보일겁니다.
uploaders 폴더 내에 있는 image_uploader.rb 파일을 열람합니다.
6. app/uploaders/image_uploader.rb 에서 일부 내용을 수정합니다.
## app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
# 자료 저장방식 (AWS 연동은 'fog'로, 로컬 저장방식은 'file'로)
storage :fog
# AWS S3 Bucket 저장 경로
# 이미지가 동일한 경로에 저장되면 똑같은 이름의 이미지가 업로드 할 시 덮어씌어질 수 있어서 이미지가 새로 추가될 때 서로 다른 경로에 이미지가 생성되게 함.
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
# 업로드 시 허용 확장자
def extension_whitelist
%w(jpg jpeg gif png)
end
# 파일 업로드 허용 용량
# 해당 부분은 주석처리 되어있음, 아래 예시에선 2MB까지만 허용
# def size_range
# 1..2.megabytes
# end
end
수정에 있어 최소한 storage :file 을 storage :fog 라고 수정해주세요.
- Chapter 2 TinyMCE에 이미지 업로드 기능 추가
1. 터미널에 입력해 새로운 Model을 추가합니다.
rails g model image alt:string hint:string file:string
그러면 db/migrate 에 'images' 라는 새로운 테이블이 생성된게 보일겁니다.
새로운 DB가 생겼으니, 이를 적용시켜야 겠죠?
아래 명령어를 1줄씩 순서대로 명령어 입력창(터미널)에 입력해주세요!
rake db:drop
rake db:migrate
2. config/tinymce.yml 파일을 열람하시고, toolbar와 plugins 목록에 'uploadimge'를 추가해 줍니다.
## config/tinymce.yml
toolbar: undo redo | forecolor | bold italic | alignleft aligncenter alignright | fontselect | code | link | uploadimage | table |
plugins:
- link
- uploadimage
- textcolor
- code
- table
3. app/models/image.rb 파일을 열람 후, 다음 mount_uploader 을 입력합니다.
class Image < ApplicationRecord
mount_uploader :file, ImageUploader
end
4. app/controllers 폴더에 새로운 파일인 images_controller.rb 을 생성해내고, 다음 내용을 입력합니다.
class ImagesController < ApplicationController
def new
@image = Image.build.params(image_params)
end
def show
@image = Image.find(params[:id])
end
private
def image_params
params.require(:image).permit(:file, :hint, :alt, :post_id, :all_notice_id)
end
end
5. app/controllers 폴더에 새로운 파일인 tinymce_assets_controller.rb 을 생성해내고, 다음을 입력합니다.
class TinymceAssetsController < ApplicationController
def create
# Take upload from params[:file] and store it somehow...
# Optionally also accept params[:hint] and consume if needed
image = Image.create(:file => params[:file])
params.permit(:file, :alt, :hint)
render json: {
image: {
url: image.file.url
}
}, content_type: "text/html"
end
end
6. config/routes.rb 파일을 열람 후, 라우터 URI 규칙을 추가합니다.
post '/tinymce_assets' => 'tinymce_assets#create'
7. 최종적으로 완성입니다! 잘 되는지 확인해보세요!!
-
이미지 영역초과 문제 및 해결방법
이미지를 업로드 할 때 작은 사이즈의 이미지는 상관없는데..
만약 게시글 내용이 나오는 영역 범위를 초과하는 그림을 업로드 하게 되면....
이렇게 됩니다......
처음에는 그냥 단순히 app/assets/stylesheets/application.css 에서
## app/assets/stylesheets/application.css
img {
width : 100%;
}
위 처럼 이미지 가로 크기를 100%로 주는 방식으로 해봤습니다.
일단, 큰 이미지는 성공입니다만(content 범위를 초과하지 않고, content 내에 이미지가 보여짐.)..
단순히 이미지 가로 크기를 100%로 설정할 경우 작은 이미지에 대해선 강제로 저렇게 크기가 늘어나는 문제가 발생하게 됩니다.
제가 이 것 때문에 약 3-5일은 고생했을겁니다.. 거의 포기할려던 찰나, 멋쟁이 사자처럼 5기의 '노종원' 님께서 답변을 주셨습니다..
다시한번 감사합니다.
우선 이분이 제시한 방법은 content 영역에 class 명을 지정해주는 겁니다.
저 같은 경우는 게시글을 보는 영역인 app/views/posts/show.html.erb 에서 'panel-body' 라는 이름으로 지어줬습니다.
참고로 class를 적용할 때
<%= @post.content.html_safe, class: "panel-body" %>
이 방법 생각하시는분들 계실텐데, 이거 안먹힙니다.
아래 코드 예시처럼 class를 적용해줘야 합니다.
<%= content_tag(:div, @post.content.html_safe, :class => "panel-body") %>
그리고, app/assets/stylesheets/application.css 에 가서 다음 CSS 코드를 추가합니다.
## app/assets/stylesheets/application.css
.panel-body img{
max-width : 100%;
max-height : 100%;
}
이렇게 하고, 다시 (사이즈가 큰 이미지를 업로드 후) 결과를 보면..
이제 이미지가 content 영역 크기에 맞게 잘 출력이 되는것을 볼 수 있습니다!
- 자료 참고
1. Github [클릭]
2. 블로그 - AWS S3 셋팅 [클릭]
3. 멋쟁이 사자처럼 4기 : 노종원 님
루비온 레일즈 Ruby on Rails ROR
'프로그래밍 공부 > Ruby on Rails : Gem' 카테고리의 다른 글
Ruby on Rails : devise 한글번역 + 'Time-Ago 번역' [Gem : devise-i18n] (0) | 2019.11.03 |
---|---|
Ruby on Rails : 로그인/회원가입 [Gem : devise] (0) | 2019.11.03 |
Ruby on Rails : 코드/계정 보안을 위한 Gem [Gem : Figaro] (0) | 2019.11.03 |
Ruby on Rails : Carrierwave와 AWS 연동을 통한 이미지 업로드 [Gem : fog-aws, carrierwave] (2) | 2019.11.03 |
Ruby on Rails : 게시판 텍스트 편집기 [Gem : TinyMCE] (0) | 2019.11.03 |