Nginx https 다시 쓰기는 POST를 GET으로 바꿉니다.


17

내 프록시 서버는 ip A에서 실행되며 사람들이 내 웹 서비스에 액세스하는 방식입니다. nginx 구성은 ip B의 가상 머신으로 리디렉션됩니다.

IP A의 프록시 서버의 경우 내 사이트에서 사용할 수 있습니다.

server {
        listen 443;
        ssl on;
        ssl_certificate nginx.pem;
        ssl_certificate_key nginx.key;

        client_max_body_size 200M;
        server_name localhost 127.0.0.1;
        server_name_in_redirect off;

        location / {
                proxy_pass http://10.10.0.59:80;
                proxy_redirect http://10.10.0.59:80/ /;

                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

}

server {
        listen 80;
        rewrite     ^(.*)   https://$http_host$1 permanent;
        server_name localhost 127.0.0.1;
        server_name_in_redirect off;
        location / {
                proxy_pass http://10.10.0.59:80;
                proxy_redirect http://10.10.0.59:80/ /;
                proxy_set_header Host $http_host;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
}

그만큼 proxy_redirect 에서 찍은 내가 재 작성을 통해 HTTP POST 요청을 전달하기 위해 nginx를 얻는 방법?

공개 IP에 도달하는 모든 내용은 다시 쓰기 때문에 443에 도달합니다. 내부적으로 가상 머신에서 80으로 전달합니다.

그러나 구성을 테스트하기 위해 아래 스크립트와 같은 파이썬 스크립트를 실행할 때

import requests

data = {'username': '....', 'password': '.....'}
url = 'http://IP_A/api/service/signup'

res  = requests.post(url, data=data, verify=False)
print res
print res.json
print res.status_code
print res.headers

을 받고 있습니다 405 Method Not Allowed. nginx에서 우리는 내부 서버에 도달했을 때 내부 GET헤더가 요청을 받았지만 내부 nginx가 요청 을 받고 있음을 발견했습니다 .POST (Python 스크립트에 표시됨).

다시 쓰기에 문제가있는 것 같습니다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까? 다시 쓰기에 댓글을 달았을 때, 80을 확실히 맞았습니다. 다시 쓰기가 내부 서버와 통신 할 수 있으므로 다시 쓰기 자체에는 문제가 없습니다. 그것은 단지 재 작성 떨어 있어요 POSTGET.

감사합니다!

(Nginx 포럼에서도 중요한 차단제이므로 질문을 할 것입니다 ...)

답변:


8

Nginx가 아니라 브라우저입니다.

RFC2616의 참고 사항 :

RFC 1945 및 RFC 2068은 클라이언트가 경로 재 지정된 요청에 대한 메소드를 변경할 수 없도록 지정합니다. 그러나 대부분의 기존 사용자 에이전트 구현은 302를 303 응답 인 것처럼 처리하여 위치 [..]에서 GET을 수행합니다.

이것은 모든 인기있는 브라우저에 해당되며 할 수있는 일은 없습니다.


@ c2h50h HTTP 사양과 비슷한 내용이 있음을 이해합니다. 하지만 Nginx에서 무엇을 할 수 있습니까? 나는이 내부 80 포트에 전달 4백43명,하지만 그들은 여전히 할 수있는 사소한 설정 의미 PUT, POST, DELETE, GET. 이전 설정에서는 군중에게 서비스를 제공하는 전면에이 추가 프록시가 없었습니다. 동일한 내부 서버 (테스트 서버)에서 동일한 구성을 가졌습니다. 잘 작동합니다.
CppLearner 2018 년

아무것도. 100 % 클라이언트 쪽입니다. 웹 서버, 웹 서버가 301 또는 302 리디렉션을 반환하면 클라이언트 측의 브라우저가 모든 유형의 요청을로 바꿉니다 GET. 서버 측 구성이 없거나 HTTP 헤더가 반환되면 변경되지 않습니다. 역사적인 이유로 (초기 브라우저는 오해로 인해 그렇게 행동했으며 사실상 표준이되었습니다).
c2h5oh

글쎄, 이것은 실제로 브라우저가 아닙니다. HTTP 프로토콜을 사용하기 때문에 브라우저라고 말할 수 있습니다. 그러나 다시, 이것은이 2 계층 구성을 수행하는 경우에만 발생하는 것처럼 보입니다. 내부 컴퓨터에 동일한 구성을 직접 배치하고 테스트를 실행하면 불평하지 않습니다. 그러나 다시, 사람들은 생산 과정에서 어떻게합니까? 일부 사람들이 비슷한 일을한다고 가정합니다 .80 만 실행하는 VM과 443을 반대로합니다. 더 나은 연습이 있다면 배우고 듣고 싶습니다.
CppLearner 2018 년

1
브라우저에서는 HTTP 클라이언트를 의미 했으며 301 또는 302가 리디렉션되면 모든 인기있는 클라이언트 POSTGET됩니다. POST는 프록시 재 지정시 POST로 유지되지만 재 작성시에는 유지되지 않습니다.
c2h5oh

1
RFC2616 다시 : If the 307 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.따라서 대부분의 브라우저는 다른 HTTP 클라이언트의 경우 동작이 무엇인지 추측 할 수 없으므로 경고 메시지를 표시합니다.
c2h5oh

1

내가 발견 POST /api/brand으로 전환되고 있었다 GET /api/brand(웹 응용 프로그램 때문에 내가 사용했다 flask-restful) "잘못된"요청을했다. 내가 사용 POST /api/brand/하면 (후행 통지 /) 성공했습니다.


Postman을 사용하여 django rest-auth login을 테스트하고 동일한 문제가 설명되었습니다. 열쇠는 POST 요청에서 후미 '/'를 무시했다는 것입니다.
Steve L
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.