티스토리 뷰

Nuxt2를 사용해 프로젝트를 진행하면서 이미지를 AWS CDN에서 불러와 클라이언트에서 fetch로 요청하던 중, CORS(Cross-Origin Resource Sharing) 문제를 겪게 되었습니다. 이 글에서는 발생한 문제와 해결 과정을 단계별로 정리하고, 각각의 선택과 이유를 설명하겠습니다.

1. 문제 상황: AWS CDN에서 이미지 로딩 시 CORS 발생

이미지 파일은 AWS S3를 기반으로 한 CDN(Content Delivery Network)에서 제공되었습니다. 클라이언트 측에서 해당 이미지를 fetch로 가져오려 하자, CORS 에러가 발생했습니다.

CORS 문제란?

CORS는 다른 도메인에서 리소스를 요청할 때 보안상의 이유로 브라우저에서 제약을 거는 정책입니다. 서버가 CORS 헤더를 통해 이 요청을 허용할지를 결정하게 되며, 이때 CORS 허용 설정이 되지 않으면 브라우저가 요청을 차단합니다.

S3 CORS 설정

CORS 문제를 해결하기 위해 가장 먼저 시도한 방법은 S3 버킷의 CORS 설정을 수정하는 것이었습니다. S3는 기본적으로 다른 도메인에서 요청을 차단하므로, 이를 허용하기 위해 S3의 CORS 정책에 적절한 설정을 추가해야 합니다.

[
    {
        "AllowedOrigins": ["*"],
        "AllowedMethods": ["GET", "POST", "PUT"],
        "AllowedHeaders": ["*"]
    }
]

위와 같이 S3에서 모든 도메인으로부터의 GET 요청을 허용하도록 설정했습니다. 하지만 이 설정만으로는 해결되지 않았습니다. S3 CORS 설정은 제대로 반영되었으나, 여전히 클라이언트에서 직접 요청할 때 에러가 발생했기 때문입니다. 이는 클라이언트와 서버 간 직접적인 통신에서 생기는 보안 문제로, 보다 근본적인 해결책이 필요했습니다.

2. 서버에서 이미지 바이너리 또는 Base64로 처리

두 번째로 생각한 방법은 서버에서 이미지를 바이너리 또는 Base64 형식으로 변환해 클라이언트로 전송하는 것이었습니다. 이를 통해 클라이언트는 더 이상 원본 URL에 직접 접근하지 않고, 변환된 데이터를 사용할 수 있기 때문에 CORS 문제를 우회할 수 있습니다.

문제점: 데이터 크기 증가

이미지를 바이너리나 Base64로 변환하는 것은 파일 크기를 증가시키는 단점이 있습니다. 특히 대용량 이미지 파일이나 고해상도 이미지의 경우, 텍스트 형식으로 전송될 때 그 크기가 크게 증가해 클라이언트에서 처리하는 데 부담이 될 수 있습니다. 이 때문에 더 나은 방법이 필요하다고 판단했습니다.

3. Nuxt2 서버사이드 API로 CORS 문제 해결

결국 선택한 해결책은 Nuxt2의 내장 서버사이드 API 기능을 활용해 서버에서 이미지를 직접 처리하는 방법이었습니다. Nuxt2는 serverMiddleware를 이용해 간단하게 서버에서 API를 제공할 수 있습니다. 이 방식은 클라이언트에서 직접 CDN에 요청하는 대신, Nuxt 서버가 대신 요청을 보내 이미지를 받아 클라이언트로 전달하는 방식입니다.

서버 to 서버 통신의 장점

서버 간 통신에서는 CORS 문제가 발생하지 않습니다. 클라이언트와 CDN 간의 통신을 Nuxt 서버가 중개하는 방식이기 때문에, 클라이언트는 Nuxt 서버에서 이미지를 받아오게 되고, CORS 문제가 발생하지 않습니다.

// api example
const app = express()
app.post('/url-to-base64', async (req, res) => {
  try {
    const { imageUrl } = req.body

    if (!imageUrl) {
      return res.status(400).json({
        message: '이미지 URL이 필요합니다.',
      })
    }

    const response = await fetch(imageUrl)
    const arrayBuffer = await response.arrayBuffer()
    const buffer = Buffer.from(arrayBuffer)

    const base64String = `data:${response.headers.get(
      'content-type'
    )};base64,${buffer.toString('base64')}`

    // 성공 응답 반환
    res.json({
      data: base64String,
      message: 'base64 완료'
    })
  } catch (error) {
    res.status(500).json({
      message: '서버 오류가 발생했습니다.',
    })
  }
})

4. 결론

이 방식으로 최종적으로 문제를 해결할 수 있었습니다. 클라이언트는 더 이상 CORS 문제를 겪지 않으며, Nuxt2 서버를 통해 안정적으로 이미지를 제공받을 수 있었습니다. 서버 간 통신을 활용함으로써 클라이언트와 원본 이미지 서버 간의 직접적인 연결을 차단해 보안상으로도 안정적이고, CORS 설정을 복잡하게 수정할 필요도 없어졌습니다.

추가 고려 사항
  • 데이터 크기: 바이너리 또는 Base64 형식으로 데이터를 전송하는 것은 문제가 될 수 있지만, 서버 간 통신을 통해 해결했습니다.
  • 보안 및 속도: 서버 간 통신은 보안적으로도 안정적이며, CDN을 사용하므로 속도 문제는 발생하지 않았습니다.

이와 같이 nuxt2의 서버사이드 기능을 활용한 해결책은 CORS 문제뿐만 아니라 보안 및 성능 측면에서도 효율적인 방법임을 확인할 수 있었습니다.
해당 문제는 nuxt2 뿐만 아니라, 어디서든 발생할 수 있는 문제임으로 문제를 만나면 해결하는데 도움이 되면 좋겠음.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함