
이번에는 도메인을 연결하기 이전에 포트포워딩과 DDNS 설정을 먼저 해보는 과정을 적었다. 그리고 공인 ip로 접속함으로써 몰랐던 CORS 이슈도 해결해보자.
이전 포스팅(맥미니에서 로컬 프로젝트 환경)에서 192.168.0.28:8082로 접속했었다. 하지만 이걸로는 사람들이 내가 만든 웹사이트에 접속할 수 없다. 이것은 언제까지고 사설(private) IP 이기 때문이다.

공인 ip로 접속해야 하는데 공인 ip가 새로운 연결 등으로 계속 바뀐다면 매번 ip 주소를 검색해서 도메인과 연결해주어야 한다.
이것의 불편함을 막기 위해 DDNS 설정이 등장한다.
iptime 관리자에 들어가서 로그인을 해준다. (192.168.0.1)

고급 설정 > 특수 기능 > DDNS 설정에 들어가서 호스트 이름과 사용자 ID를 설정한다.
DDNS를 등록하면 위 사진처럼 호스트 이름과 정보를 볼 수 있다.
👉 DDNS 설정 참고 https://blog.naver.com/cjs0308cjs/2232585759=49
이제 호스트이름.iptime.org로 접속하면 내 웹사이트를 볼 수 있다.

저 뒤에 붙은
:8080은 포트포워딩 설정인데 그냥 호스트명.iptime.org로만 접속하면 내 사이트를 못 찾고 빙글빙글 계속 돌기만 한다;;
222.112.27.63를 외우는 것보다 호스트명를 외우는 것이 당연 더 쉽다. 또한 공인 ip가 변경되든지 말든지 나는 호스트명만 알고 있으면 되니 도메인을 구입했을 때 DDNS 설정을 해두고 이와 연결하는 것이 관리하기 더 편하다.
외부에서 들어온 요청을 내 웹사이트의 nginx 웹 서버로 가도록 포워딩 작업을 해줬다.

아까의 ip 관리자 페이지에 가서 고급 설정 > NAT/라우터 관리 > 포트포워드 설정에 들어가서 아래처럼 설정했다. 나는 8080 포트로 접속 시 내 웹 서버의 8082 포트로 연결되도록 했다. (내 사설 ip도 고정으로 바꿨다)

공인 ip나 .iptime.org로 접속하면 프론트에서 백엔드 api를 호출할 때 CORS 이슈가 발생했다. 에러는 대략 줄여서 백엔드에서는 jvk(중략).iptime.org:8080에 대한 cors 처리가 되어 있지 않다는 내용이다.
백엔드 프로젝트에서 cors 설정 경로에 jvk(중략).iptime.org:8080을 추가한다. 결과적으로 실패 ❌
nginx.conf를 변경한다.
/api 경로로 location 블록을 추가해서 프록시 설정을 해보기도 하고, 웹서버 포트를 백엔드 경로로 설정해 보기도 했다. 결과적으로 전부 실패 ❌
내가 본 에러가 아래 블로그 내용처럼이었는데, origin보다 접근 수준이 낮은 네트워크에 액세스 요청을 할 때 CORS가 발생한다고 한다.
그렇다면 외부에서 웹서버에 요청을 보내더라도 프론트단에서 백단으로는 localhost로 내부 통신을 하도록 뭔가를 감싸줘야 하는 거 아닌가...? 생각을 했다.
그 감싸다? 다시 쓰다? 생각해보다가 기존 vue 프로젝트의 /api 경로에 대한 target 설정이 기억났다. + next.js cors 이슈로 검색하면서 답을 찾았다.
문제는 클라이언트와 서버가 다른 도메인이었던 것이 원인이었고, 외부 요청이 내부 로컬 서버로 전달되도록 설정하는 방법이다.
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: false,
async rewrites() {
const apiUrl = process.env.NEXT_PUBLIC_URL || 'http://localhost:8080'; // 로컬 기본 값
return [{
source: '/api/:path*',
destination: `${apiUrl}/api/:path*`,
},]
},
images: {
domains: ['res.cloudinary.com'],
},
};
export default nextConfig;
무조건 localhost:8080을 하드코딩하면 render.com 등에 배포할 때 위험이 생기니까 환경변수로부터 읽도록 한다.
호출부는 아래처럼 바뀐다. 앞에 매번 붙였던 환경변수 경로가 사라진다.
export const fetchChatRoomsBySrch = async ({ queryKey }: { queryKey: string[] }) => {
const userEmail = queryKey[1];
// const response = await fetch(process.env.NEXT_PUBLIC_DOMAIN_URL + '/api/chat/search/room?userEmail=' + userEmail);
const response = await fetch('/api/chat/search/room?userEmail=' + userEmail);
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
};
처음에는 백엔드 서버에서 localhost, .iptime.org 경로로 다 설정을 추가해도 왜 CORS 이슈가 해결되지 않지? 라고 의문이 들었다.
CORS 정책은 Origin 헤더를 보고 결정되기 때문에 Origin 도메인에 맞는 허용 설정을 해야 합니다.
CORS를 단순 경로로만 보지 않고 헤더, Origin으로 정책이 결정되어서 그런 것이 아닐까 추측해본다.
🔥 CORS 이슈를 위해서는 프론트와 백엔드 모두 설정이 필요하다는 것을 잊지 않기