지피지기 백전백퇴

CORS 없는 서비스 구성


개요

기존에 CORS 설정 등의 작업을 하면서 삽질을 좀 했는데, 아무래도 브라우저들이 3rd party cookie를 점차 금지하는 분위기인 것 같아서 3rd party cookie를 이용해서 로그인 세션을 관리하는 API 서버도 영향을 받지 않을까 싶다. 다만 GraphQL API 서버는 Rust로 만들었고, 웹 앱은 Next.js로 만들고 있는데, 이걸 어떻게 구성해야 번거로운 CORS 설정을 피할 수 있을까?

쉬운맛 - 최종 서비스 구성

Caddy 기준으로 특정 url path에 대해서 다른 reverse proxy를 설정하는 방법이 있다. Nix 설정파일 기준으로:

"app.awesome.website" = {
  extraConfig = ''
    handle_path /gql* {
      reverse_proxy localhost:11111
    }
    reverse_proxy localhost:22222
  '';
};

이렇게 설정하면 /gql로 시작하는 url은 localhost:11111로 라우팅되고, 나머지 url은 localhost:22222로 라우팅된다. 하지만 둘 모두 app.awesome.website 도메인을 공유하므로 CORS 문제는 없어진다.

번거로운맛 - 개발 서버 구성

Next.js를 통해 개발하는 개발 서버 - 여기서 말하는 개발서버란 next dev 명령어로 실행하는, 보통 localhost:3000에서 동작하는 서버를 말한다 - 에서 위에서 만든 Caddy 설정을 알아먹을 리가 없으니, 킹쩔수 없이 개발서버에서 이해할 수 있는 reverse proxy 설정을 따로 만들어줘야 한다.

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  output: "standalone",
  async rewrites() {
    return [
      {
        source: '/gql/:path*',
        destination: 'https://app.awesome.website/gql/:path*',
      },
    ]
  },
}

module.exports = nextConfig

이론적으로는 Caddy 설정 없이 이것만 써도 웹앱을 위해 돌리는 standalone 서버에서 해당 rewrite를 동작시키기 때문에 작동하겠지만, 1. 왠지 javascript 앱에 주는 부담을 줄이는게 맞지 않나 싶어서, 2. 왠지 next.js 특화 설정은 가능한 한 줄이고 싶어서 - next.js가 영리 목적으로 개발되다보니 많은 기능이 유료 서비스에 맞춰서 개발되지 않나 하는 의심이 있다 - 두가지 설정을 모두 적용해 둔 상태다.

매운맛 - 서버와 웹을 동시에 개발할 때

그런데 만약 서버랑 웹을 동시에 개발해야 해서, API 서버와 웹 서버를 모두 로컬에서 돌려야 한다면?

그런거 하지마라.. 최소한 난 안했다. 굳이 할거라면 앱의 destination을 그때그때 개발 서버의 주소로 지정해줘야 하는데, 너무 번거로울 것 같다.

결론

이렇게 설정이 쉬울 줄 알았으면 진작에 CORS 설정 때려치고 이쪽으로 가는 거였는데…