Skip to content

Commit

Permalink
이미지 업로드 시 key/파일명 의 경로로 s3에 업로드하도록 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
JunBye committed Jan 14, 2025
1 parent 393fe3a commit 5100eb8
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import java.nio.file.Paths
import java.util.Date

@RestController
@RequestMapping("/api/images")
Expand All @@ -40,32 +38,18 @@ class ImageController(
return try {
val file = request.file
val key = request.key.trim()

val tempFile = Paths.get(System.getProperty("java.io.tmpdir"), file.originalFilename).toFile()
file.transferTo(tempFile) // MultipartFile을 임시 파일로 저장

imageService.uploadFile(tempFile.absolutePath, key) // S3에 업로드
tempFile.delete() // 임시 파일 삭제

ResponseEntity("Image uploaded successfully with key: $key", HttpStatus.OK)
val fileUrl = imageService.uploadFile(file, key) // S3에 업로드 및 경로 저장
ResponseEntity.ok("Image uploaded successfully with key: $key, URL: $fileUrl")
} catch (e: Exception) {
ResponseEntity("Failed to upload image: ${e.message}", HttpStatus.INTERNAL_SERVER_ERROR)
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body("Failed to upload image: ${e.message}")
}
}

@GetMapping("/{key}")
fun getImageSignedUrl(
@PathVariable("key") key: String
): ResponseEntity<String> {
@GetMapping("/get-signed-url/{key}")
fun getSignedUrl(@PathVariable key: String): ResponseEntity<String> {
return try {
val expirationDate = Date(System.currentTimeMillis() + 3600_000) // 1시간 유효

val signedUrl = imageService.generateSignedUrl(
"https://d3m9s5wmwvsq01.cloudfront.net",
key,
expirationDate
)

val signedUrl = imageService.generateSignedUrl(key)
ResponseEntity.ok(signedUrl)
} catch (e: Exception) {
ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
Expand Down
102 changes: 69 additions & 33 deletions src/main/kotlin/com/example/toyTeam6Airbnb/Image/ImageService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ import com.amazonaws.services.cloudfront.CloudFrontUrlSigner
import com.amazonaws.services.cloudfront.util.SignerUtils
import org.springframework.beans.factory.annotation.Value
import org.springframework.stereotype.Service
import org.springframework.web.multipart.MultipartFile
import software.amazon.awssdk.core.sync.RequestBody
import software.amazon.awssdk.regions.Region
import software.amazon.awssdk.services.s3.S3Client
import software.amazon.awssdk.services.s3.model.PutObjectRequest
import java.io.File
import java.io.IOException
import java.nio.file.Paths
import java.security.PrivateKey
import java.util.Date
import java.util.UUID

@Service
class ImageService() {
Expand All @@ -28,44 +31,77 @@ class ImageService() {
private val cloudFrontUrl: String = "https://d3m9s5wmwvsq01.cloudfront.net"

// 파일 업로드 메서드
fun uploadFile(filePath: String, key: String) {
println("Uploading File with key : $key") // 디버깅
s3Client.putObject(
PutObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build(),
RequestBody.fromFile(Paths.get(filePath))
)
}
fun uploadFile(file: MultipartFile, key: String): String {
val fileName = "$key/${UUID.randomUUID()}_${file.originalFilename}" // 고유 경로 생성
try {
val tempFile = Paths.get(System.getProperty("java.io.tmpdir"), file.originalFilename).toFile()
file.transferTo(tempFile)

// // 파일 다운로드 메서드
// @Transactional
// fun downloadFile(key: String, destination: String) {
// s3Client.getObject(
// GetObjectRequest.builder()
// .bucket(bucketName)
// .key(key)
// .build(),
// Paths.get(destination)
// )
// }
s3Client.putObject(
PutObjectRequest.builder()
.bucket(bucketName)
.key(fileName)
.build(),
RequestBody.fromFile(tempFile.toPath())
)
tempFile.delete()

// CloudFront signed URL 생성 메서드
fun generateSignedUrl(
domain: String,
key: String,
expiration: Date
): String {
// privateKey와 keyPairId는 GitHub Secrets에서 가져온 값이 자동으로 주입됨
if (privateKey.isBlank()) {
throw IllegalStateException("Private key is not configured or is blank")
// DB에 파일 경로 저장 saveFilePathToDatabase(key, fileName) (추후 Room, User 엔티티에 추가식으로 수정)
// ProfileImageUpload, RoomImageUplaod 형식으로 할것
} catch (e: IOException) {
throw RuntimeException("S3 업로드 중 에러가 발생했습니다: ${e.message}", e)
}
if (keyPairId.isBlank()) {
throw IllegalStateException("Key Pair ID is not configured or is blank")

return "https://$bucketName.s3.amazonaws.com/$fileName"
}

// CloudFront signed URL 생성 메서드
fun generateSignedUrl(key: String): String {
try {
if (privateKey.isBlank()) {
throw IllegalStateException("Private key is not configured or is blank")
}
if (keyPairId.isBlank()) {
throw IllegalStateException("Key Pair ID is not configured or is blank")
}
// S3 객체 경로 생성 (key 폴더 사용)
val filePath = "$key/"

// 만료 시간 설정 (예: 1시간 후)
val expirationDate = Date(System.currentTimeMillis() + 3600_000)

// CloudFront 서명된 URL 생성
// 1. 임시 파일 생성 및 비공개 키 쓰기
val tempFile = File.createTempFile("privateKey", ".pem")
tempFile.deleteOnExit() // 애플리케이션 종료 시 자동 삭제
tempFile.writeText(privateKey)

// 2. Private Key 객체 로드
val privateKeyObj: PrivateKey = SignerUtils.loadPrivateKey(tempFile)
return CloudFrontUrlSigner.getSignedURLWithCannedPolicy(
"https://d3m9s5wmwvsq01.cloudfront.net/$filePath",
keyPairId, // Key Pair ID
privateKeyObj,
expirationDate
)
} catch (e: Exception) {
throw RuntimeException("Signed URL 생성 중 에러 발생: ${e.message}", e)
}
return createSignedUrl(domain, key, privateKey, keyPairId, expiration)
}
// fun generateSignedUrl(
// domain: String,
// key: String,
// expiration: Date
// ): String {
// // privateKey와 keyPairId는 GitHub Secrets에서 가져온 값이 자동으로 주입됨
// if (privateKey.isBlank()) {
// throw IllegalStateException("Private key is not configured or is blank")
// }
// if (keyPairId.isBlank()) {
// throw IllegalStateException("Key Pair ID is not configured or is blank")
// }
// return createSignedUrl(domain, key, privateKey, keyPairId, expiration)
// }

// CloudFront 서명 URL 생성 메서드
// createSignedUrl 메서드 구현
Expand Down

0 comments on commit 5100eb8

Please sign in to comment.