문제 상황
사전 설명
- Django 프로젝트 이미지를 빌드한 Docker 컨테이너를 8000번 포트에 띄움
- Nginx로
api.domain.com
으로 들어오는 요청을localhost:8000
으로 라우팅 - Django 프로젝트에서는 회원가입에 성공하면 입력된 이메일로 인증 메일을 발송하고 있음
문제 발생
- 배포된 서버인데도 인증 링크의 도메인 부분이
localhost:8000
으로 표시된다...
해결
원인
1class MyDocument extends Document {2 render() {3 return (4 <Html>5 <Head>6 <link7 rel="stylesheet"8 href="https://unpkg.com/dracula-prism/dist/css/dracula-prism.css"9 ></link>10 </Head>11 <body>12 <Main />13 <NextScript />14 </body>15 </Html>16 );17 }18}1920(function someDemo() {21 var test = "Hello World!";22 console.log(test);23})();24return () => <App />;
1def build_absolute_uri(request, location, protocol=None):2 """request.build_absolute_uri() helper34 Like request.build_absolute_uri, but gracefully handling5 the case where request is None.6 """7 from .account import app_settings as account_settings89 if request is None:10 site = Site.objects.get_current()11 bits = urlsplit(location)12 if not (bits.scheme and bits.netloc):13 uri = '{proto}://{domain}{url}'.format(14 proto=account_settings.DEFAULT_HTTP_PROTOCOL,15 domain=site.domain,16 url=location)17 else:18 uri = location19 else:20 uri = request.build_absolute_uri(location)21 (...)
위 코드는 allauth
패키지의 utils 코드 일부인데, 인증 링크의 도메인 부분을 생성하는 코드이다. 이 함수를 실행할 때 request 객체가 전달된다면 request.build_absolute_uri
를 실행하여 도메인 주소를 얻는데, 이는 request 객체가 가지고 있는 uri 주소를 기반으로 절대 URI를 가져오는 것이다. 참고 - 공식 문서
그런데 앞서 Nginx 서버 라우팅으로 인해 api.domain.com
에서 localhost:8000
으로 호스트 네임이 변경되었다. 즉 request가 가지고 있는 도메인 주소는 localhost:8000
이다.
해결 방법
Nginx의 default.conf 파일에서 api.domain.com
을 라우팅하는 부분에 header를 설정해 주는 부분을 추가해야한다.
proxy_set_header Host $http_host;
를 추가한다.
1server {2 listen 80;3 listen [::]:80;4 server_name api.domain.com;5 location / {6 proxy_pass http://localhost:8000;7 proxy_set_header Host $http_host;8 }9}
- 저장 후
sudo systemctl restart nginx
커맨드로 Nginx를 다시 실행한다.