redirect_uri mismatch when gunicorn behind nginx reverse proxy
프로덕션 배포를 한번 해두려고 postgresql 연결하고, cdn 설정하고 마지막으로 도메인 연결하는데...
블로그에선 소셜로그인이 없으니 만나지 못했던 문제가 나를 기다리고 있었으니...
nginx 에서 https://server 연결을 먼저 받고, proxy_pass http://127.0.0.1:8080; 로 연결해주는 설정이다.
그냥 글 쓰고 읽고 하는건 문제가 없는데, google login 을 하려는 순간 문제가 발생했다.
browser https://a.b.c ---> nginx proxy pass to http://127.0.0.1:8080 ---> gunicorn listening on 127.0.0.1:8080
대강 이러한 구조인데... 문제의 시작은 social app 로그인을 할 때에 allauth 가 redirect_uri 를 사이트 정보에 예쁘게 넣어둔 것을 쓰지 않고, request.META 의 정보를 쓴다는 것이다. 그렇다, REQUEST-내가 받은 요청 정보를 쓰는 것. 개발단계에서야 어차피 localhost 에 바로 접근할 수 있는 상황이니 문제가 없지만, 프로덕션 환경에서는 https://a.b.c/어쩌고저쩌고 이런 redirect_uri 가 만들어져야 하는데, gunicorn 이녀석이 받은 요청은 nginx 가 로컬에서 한거다. 그러니까, redirect_uri 를 http://localhost:8080/어쩌고저쩌고 이렇게 만들어버린다는 것. 보면 1. Scheme, 2. Host, 3. Port 가 모두 다 틀렸다 ㅋㅋㅋ
개발단계에서 등록했던 redirect_uri 들은 http://localhost:8000 이라 포트번호가 달라서 모르는 redirect_uri 라고 구글이 계속 400에러를 리턴했다.
구글링을 해보니 스택오버플로에서 나와 완전 같은 상황의 질문이 있었는데, 답은 없었다.
좀 더 뒤져보니, django-allauth 이슈에 관련 내용이 있어서 이걸 보고 해결했다. 아래 설정 중에 몇개가 빠지면 위에 얘기한, scheme, host, port 중 한두개씩은 안맞게 된다. http://a.b.c/어쩌고저쩌고 튀어나온다거나 https://localhost/어쩌고저쩌고 한다거나...
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://127.0.0.1:8080;
이렇게 넣고 문제 해결. 나중에 또 삽질할까봐 적어둔다.