< 2025.02.25 업로드 >
🆘 CORS 오류와의 만남
SSAFY 2학기 공통 프로젝트를 진행하면서 예상치 못한 문제에 부딪혔습니다. 로컬 네트워크에서 웹소켓을 활용한 채팅 기능을 테스트하는 중이었죠. 간단하게 HTML로 테스트 페이지를 만들고, Spring Security에서 CORS 설정을 해두었습니다.
configuration.setAllowedOrigins(Arrays.asList(
"http://127.0.0.1:5173",
// 다른 허용 URL들...
));
그런데 이상하게도 계속 CORS 오류가 발생했습니다. 디버깅을 하다가 문득 설정에 localhost를 추가해 보았습니다.
configuration.setAllowedOrigins(Arrays.asList(
"http://127.0.0.1:5173",
"http://localhost:5173",
// 다른 허용 URL들...
));
그제야 문제가 해결되었습니다.
127.0.0.1이랑 localhost는 같은 것 아닌가요?
🆚 localhost와 127.0.0.1의 차이
💡 Loopback이란?
localhost와 127.0.0.1을 이해하기 위해서는 먼저 '루프백' 개념을 알아야 합니다. 루프백은 네트워크 패킷이 물리적인 네트워크 인터페이스를 통해 외부로 나가지 않고, 컴퓨터 내부에서 다시 자신에게 돌아오는 가상의 네트워크 인터페이스입니다.
1. 물리적 네트워크 사용 안 함
데이터가 실제 네트워크 카드를 통해 전송되지 않습니다.
2. 내부 프로세스 간 통신
같은 컴퓨터 내의 프로세스들이 네트워크 프로토콜을 사용해 통신할 수 있게 해줍니다.
3. 네트워크 테스트
물리적 네트워크 연결 없이도 네트워크 애플리케이션을 테스트할 수 있습니다.
루프백 인터페이스는 IPv4에서는 `127.0.0.1`, IPv6에서는 `::1`이라는 IP 주소를 가지며, 일반적으로 'localhost'라는 호스트명이 127.0.0.1로 매핑됩니다.
따라서 localhost나 127.0.0.1로 요청을 보내면, 해당 요청은 외부 네트워크로 나가지 않고 컴퓨터 내부의 루프백 인터페이스를 통해 자기 자신에게 돌아오게 됩니다. 하지만, 형태와 처리 방식에 차이가 있어 CORS에서 다르게 인식되는 문제가 발생합니다.
💡 127.0.0.1
- IP 주소입니다. (IPv4에서 루프백 인터페이스로 예약됨)
- 네트워크 스택을 통해 데이터가 전송되지만, 물리적 네트워크 인터페이스는 거치지 않음
- DNS 조회 없이 직접 사용 가능
💡 localhost
- 호스트명입니다. 일반적으로 127.0.0.1로 해석됨
- 운영체제의 /etc/hosts 파일이나 DNS를 통해 변환됨
- 매핑이 변경될 수 있으며, IPv6에서는 ::1로 해석될 수도 있음
hosts 파일과 DNS의 역할
호스트명이 IP 주소로 변환되는 과정에서 중요한 역할을 하는 것이 hosts 파일입니다. 이 파일은 특정 도메인 이름을 특정 IP 주소에 연결하는 역할을 합니다.
따라서 DNS 서버를 사용하지 않더라도, hosts 파일만으로 도메인 이름 해석이 가능합니다.
Windows의 hosts 파일을 확인해보면 종종 다음과 같이 localhost 관련 설정이 주석 처리되어 있는 것을 볼 수 있습니다.
그러나 Windows에서는 이러한 매핑이 기본적으로 DNS Resolver에 의해 내부적으로 처리되므로, 이 설정이 주석 처리되어 있어도 localhost는 여전히 127.0.0.1로 해석됩니다.
여기서 핵심적인 의문이 생기는데요,
결국 localhost = 127.0.0.1 이지만, cors 설정에서는왜 다르게 취급되는걸까요?
🧐 브라우저와 CORS의 관점에서 본 차이점
이유는 브라우저의 Same-Origin Policy와 CORS 정책에 있습니다. 브라우저는 보안상의 이유로 '출처(Origin)'를 엄격하게 구분합니다. 출처는 다음 세 가지 요소의 조합으로 정의됩니다.
1. 프로토콜(http, https)
2. 호스트명(domain)
3. 포트 번호
여기서 핵심은 브라우저가 localhost와 127.0.0.1을 서로 다른 호스트명으로 인식한다는 점입니다. 비록 두 주소가 같은 IP를 가리키더라도, 브라우저의 관점에서는 다른 출처로 간주됩니다.
예를 들어
이 둘은 기술적으로 같은 서버를 가리키지만, 브라우저는 이를 서로 다른 출처로 취급합니다.
따라서 서버의 CORS 설정에서 http://127.0.0.1:5173만 허용했다면, 브라우저가 http://localhost:5173으로 요청할 경우 다른 출처로 판단하여 CORS 오류가 발생하게 됩니다.
개발 환경에서 발생할 수 있는 문제
로컬 개발 환경에서는 흔히 두 주소를 혼용해서 사용합니다.
- 프론트엔드는 localhost:3000에서 실행
- 백엔드는 127.0.0.1:8080에서 실행
이처럼 주소를 혼용하면 CORS 오류가 발생할 가능성이 높아집니다. 따라서 CORS 설정에서는 반드시 두 주소를 모두 허용 목록에 추가해야 합니다.
✅ 그 외 알아두면 좋은 차이점
- DNS 조회: localhost는 DNS 조회 또는 hosts 파일을 통해 변환되지만, 127.0.0.1은 직접적인 IP 주소라 DNS 조회가 필요 없습니다.
- IPv6 지원: localhost는 IPv6에서 ::1로 매핑되지만, 127.0.0.1은 IPv4 전용 주소입니다.
- 성능 차이: 일반적으로 127.0.0.1이 DNS 조회 과정이 없어 미세하게 더 빠를 수 있습니다.
항목 | hosts 파일 | DNS 서버 |
위치 | 로컬 컴퓨터의 운영체제 파일 | 네트워크 또는 인터넷에 위치 |
우선순위 | 항상 우선 | hosts 파일이 없는 경우에만 사용 |
유효 범위 | 해당 컴퓨터에서만 적용 | 전 세계적으로 사용 가능 |
사용 목적 | 테스트, 특정 사이트 차단, 로컬 네트워크 | 전역적인 도메인 이름 해석 제공 |
유지보수 | 수동으로 업데이트 필요 | 자동 업데이트 및 중앙 집중 관리 |
📌 결론
겉보기에는 같아 보이는 localhost와 127.0.0.1이지만, 웹 브라우저와 CORS 정책의 관점에서는 명확한 차이가 있습니다. 로컬 개발 시 CORS 관련 문제를 방지하려면 두 주소를 모두 허용 목록에 추가하는 것이 좋다고 합니다. 이런 사소한 차이가 개발 과정에서 디버깅에 많은 시간을 허비하게 만들 수 있습니다. 하지만 이제 그 차이를 이해했으니, 앞으로는 비슷한 문제를 더 빠르게 해결할 수 있을 것입니다. 개발은 때로 당연하게 여겨지는 것들에 대해 깊이 이해하는 과정이기도 하니까요!
🗂️ References
https://pstor.dev/network-story/Difference-between-localhost-and-127-0-0-1/
https://www.sktenterprise.com/bizInsight/blogDetail/dev/10267
https://jettstream.tistory.com/622
👀 SSAFY의 다양한 소식과 이야기를 더 알고 싶다면
📌 SSAFYcial 인스타그램
📌 SSAFY 홈페이지
'SSAFY' 카테고리의 다른 글
[싸피셜이 알려드림: SSAFY편] SSAFY를 만나고 달라진 일상 (0) | 2025.02.27 |
---|---|
[싸피셜이 알려드림: SSAFY편] 13기 모바일 트랙의 이야기: 허지명 교육생 인터뷰 (1) | 2025.02.25 |
[싸피셜이 알려드림: 기술편] Filter와 Interceptor의 차이 (0) | 2025.01.07 |
[싸피셜이 알려드림: 기술편] DispatcherServlet이 뭘까? (0) | 2024.12.22 |
[싸피셜이 알려드림: SSAFY편] 게임으로 평가받는다? 배틀싸피 등장! (2) | 2024.12.22 |