2011-07-11 63 views
19

我想將對我的Flask應用程序的請求代理到本機上運行的另一個Web服務。我寧願爲此使用Flask,而不是我們的高級nginx實例,以便我們可以重用我們現有的內置於我們應用中的認證系統。我們越能保持這種「單點登錄」越好。用Flask代理另一個Web服務

有沒有現成的模塊或其他代碼來做到這一點?試圖將Flask應用程序連接到類似httplib或urllib的東西被證明是一種痛苦。

+0

同樣這個問題是相關的。 –

+0

你對httplib有什麼具體問題? –

+0

@jd:鑑於燒瓶位於WSGI的應用程序端,我不確定是否能夠有效轉發所有數據。例如,Flask請求對象似乎不包含我想要傳入httplib的原始請求(甚至請求頭)。這不是不可能的,這只是一個痛苦,我希望已經有一個現有的模塊。 –

回答

8

我有一個在基於Werkzeug的應用程序中使用httplib的代理的實現(如你的情況,我需要使用webapp的認證和授權)。

儘管Flask文檔沒有說明如何訪問HTTP標頭,但您可以使用request.headers(請參閱Werkzeug documentation)。如果您不需要修改響應,並且代理應用程序使用的標頭是可預測的,那麼代理服務就顯得很直接。

請注意,如果您不需要修改響應,則應該使用werkzeug.wsgi.wrap_file來包裝httplib的響應流。這允許將開放的OS級文件描述符傳遞給HTTP服務器以獲得最佳性能。

+0

謝謝,我今天下午砍了一些東西。不過,由於httplib不能很好地處理它們,因此存在各種cookies問題。不幸的是,我想我需要修改響應來做一些簡單的URL重寫(即> –

+0

在我的情況下,只有一個cookie需要捕捉,所以正則表達式解析了它,而設置Python的cookie庫更容易。 –

7

我原來的計劃是面向公衆的網址是http://www.example.com/admin/myapp代理http://myapp.internal.example.com/。在那條路上走向瘋狂。

大多數web應用程序,特別是自託管應用程序,都假定它們將運行在HTTP服務器的根目錄下,並執行像絕對路徑引用其他文件的操作。要解決這個問題,你必須重寫所有的URL:位置標題和HTML,JavaScript和CSS文件。

我做了write a Flask proxy blueprint這是做到了這一點,雖然它對我真正想要代理的一個webapp非常有效,但它不可持續。這是一大堆正則表達式。

最後,我在nginx中建立了一個新的虛擬主機,並使用它自己的代理。由於兩者都位於主機的根部,所以URL重寫幾乎是不必要的。 (以及nginx的代理模塊處理的必要性很小。)被代理的web應用程序執行自己的身份驗證,現在已經足夠好了。

+0

將再次讀取7/10 –

19

我花了很多時間在這個相同的事情上工作,並最終找到了一個解決方案,使用請求庫似乎運作良好。它甚至可以在一個響應中處理設置多個cookie,這需要進行一些調查才能弄清楚。這裏的燒瓶視圖功能:做舊的瀏覽器IE7一樣不支持跨域安全的AJAX服務時

from flask import request, Response 
import requests 

def _proxy(*args, **kwargs): 
    resp = requests.request(
     method=request.method, 
     url=request.url.replace('old-domain.com', 'new-domain.com'), 
     headers={key: value for (key, value) in request.headers if key != 'Host'}, 
     data=request.get_data(), 
     cookies=request.cookies, 
     allow_redirects=False) 

    excluded_headers = ['content-encoding', 'content-length', 'transfer-encoding', 'connection'] 
    headers = [(name, value) for (name, value) in resp.raw.headers.items() 
       if name.lower() not in excluded_headers] 

    response = Response(resp.content, resp.status_code, headers) 
    return response 
+1

剛剛編輯以從請求標頭中刪除「主機」並從響應標頭中刪除一些項目。 – Evan

+1

'標題'似乎沒有用? – luckydonald

+1

@luckydonald我認爲它現在是固定的。感謝您指出了這一點。 – Evan