2013-11-01 4 views
1

나는 관련 질문을했다 here. 기본적으로 API를 Flask으로 만들었습니다.이 API는 Flask 앱 자체를 실행하는 동일한 컴퓨터에서만 POST 할 수 있기를 원합니다. 다른 모든 POST 요청은 Unauthorized 401 응답을 받아야합니다.remote_addr 헤더를 사용하여 POST API에 대한 액세스를 제한하는 방법은 무엇입니까?

이 시점에서 어떻게 달성 할 수 있는지 조금 혼란스러워졌습니다. 다른 곳에서 (더 이상 기억할 수 없다) REMOTE_ADDR 헤더/필드를 비교하는 것이 적절한 방법이라는 것을 알았다. Here은 최소한 하나의 예입니다.

if request.environ.get('REMOTE_ADDR', '127.0.0.1') != '127.0.0.1': 
    abort(401) 
post_data = request.form 
DPC().store(post_data) 
return jsonify(post_data), 201 

그러나, 이러한 변경 사항을 구현 한 후, 난 여전히 외부 시스템에서 API에 게시 할 수 있었다 :

는 내가보기 기능에서이 작업을 수행 할 것이라고 생각 몇 가지 코드를 썼다. 데프 test_external_post_fails (자동) :

my_data = { 
     ... 
    } 
    result = self.client.post('/daily_population_changes', 
        data=my_data, 
        environ_overrides={'REMOTE_ADDR': '127.0.0.2'}) 
    assert result.status_code == 401 

테스트는 성공 나는이 기능을 쓴 테스트는 근본적인 문제가 무엇인지 모순된다. 그러나 질문은 정밀도와는 달리 정확도 중 하나입니다. 여기서 올바른 것을 테스트하고 있습니까? Werkzeug environment에있는 원격 요청에 실제로 '127.0.0.1'이 아닌 REMOTE_ADDR에 대한 (null이 아닌) 값이 있습니까?

실제 요청한 값만큼 실제 요청 값을 검사 할 수 없었습니다 (프로덕션 서버에서) POST 허용 목록 작성이 성공하지 못했습니다. 아마 누군가 이미 이것에 대한 통찰력을 가지고 있습니다. 그렇지 않으면 조금 더 많은 기계에 액세스 할 수 있습니다.

감사합니다.

+1

당신은 어떤 종류의 프록시 (예를 들어, Flask에 Nginx 전달 사용) 뒤에 Flask를 실행하고 있습니까? 그렇다면 Nginx는 아마도 루프백 인터페이스를 사용하는 새로운 요청을하고 Flask는 요청을 보게됩니다 (따라서 REMOTE_ADDR은 127.0.0.1이됩니다). 자세한 내용은 [이 질문] (http://stackoverflow.com/questions/4773969/is-it-safe-to-trust-serverremote-addr)을 참조하십시오. –

+0

예, 있습니다! 팁 주셔서 감사, 나는 이것을 조사하고있다. –

+0

기본적으로 Nginx는 사용자의 IP를'X-Forwarded-For' 헤더에 저장합니까? 와우, 그걸 알아 내려면 잠시 걸렸을거야. –

답변

1

당신을 트립하고있는 것 중 하나가 request.environ.get('REMOTE_ADDR', '127.0.0.1')입니다. get() 메서드가 dict이면 첫 번째 키가없는 경우 두 번째 값을 반환합니다. 따라서 어떤 이유로 든 'REMOTE_ADDR'이 없으면 자동으로 '127.0.0.1'으로 입력합니다. 대신

if request.environ.get('REMOTE_ADDR', False) == '127.0.0.1': 

: 같은

보십시오 뭔가. 그게 도움이 되니?

+0

그것은 내가 이것을 다시 엉망으로 할 의지가있는 것을 들여다 보았던 그 다음 흔적이었다. 문제는,'environ [ 'REMOTE_ADDR']'가 항상 설정되어 있는지 정말로 확신 할 수 없습니다. 사실, 때로는 알지 못합니다. (기본값을 추가 할 때 직접 딕트에 액세스하는 중 오류가 발생했습니다.) 속성의 이름이 원격 주소임을 제안하는 것처럼 보이기 때문에 설정되지 않았다면 로컬인지 아닌지를 추측 할 수있었습니다. –

+0

그 이유는'environ [ 'REMOTE_ADDR]'이 항상 리버스 프록시 서버가 설정하고 있다는 것이 아니라 테스트 할 때 사용하지 않았기 때문입니다. 필자는 테스트에서 environ_overrides = { 'REMOTE_ADDR': '127.0.0.1'} 매개 변수를 추가하고'127.0.0.1 '과 비교하기 위해 단순히'foo'라는 이름을 제공했습니다. 그러나 서버는 여전히 내 로컬 컴퓨터에서 POST 요청을 받아들입니다. –