2013-03-17 14 views
31

Ursprünglich habe ich versucht, eine Ajax-Anfrage von meiner Client-Seite an eine Drittanbieter-URL zu senden, aber es scheint, dass der Browser Sicherheitsprobleme damit hat. Ich dachte daran, einen Ajax an die Server-Seite zu senden, von dort eine GET-Anfrage an die dritte Partei zu senden, die Antwort zu erhalten und sie an die Client-Seite zurückzusenden. Wie kann ich das mit Kolben tun?Wie kann ich eine GET-Anfrage von meiner flask-App an eine andere Site senden?

Antwort

36

Installieren Sie das requests Modul (viel schöner als urllib2 verwendet wird) und dann eine Route definieren, die die notwendige Anforderung macht - so etwas wie:

import requests 
from flask import Flask 
app = Flask(__name__) 

@app.route('/some-url') 
def get_data(): 
    return requests.get('http://example.com').content 

Je nach obwohl einzurichten, würde es besser sein, zu konfigurieren Ihr Webserver, um den Proxy unter einer bestimmten URL an die Ziel-Site zu übertragen.

+0

urllib2 Antrag Verwendung in meinem Host einen Fehler verursacht, meine Vermutung ist, Diese Installationsanfrage würde das Gleiche tun (habe das Traceback aber noch nicht untersucht) ... Gibt es dafür keine eingebaute Flask-Funktion? @ Jon Clements – user1639431

+0

@ user1639431 nein - keine eingebaute Funktion - ist Flask läuft unter Apache2/nginx? –

+0

Keine Ahnung, es ist ein Cloud-Service, aber mein Geld ist auf Nginx. Wie auch immer, ich schaute auf die Traceback, und sowohl urllib2 und Anfragen geben "Verbindung abgelehnt". Ich habe kein Problem, diese URL von meinem cli zu öffnen/curl, kann die Quelle dieses Problems nicht verstehen. @ Jon Clements – user1639431

8

Flask allein verfügt nicht über diese Funktion, aber es ist eine einfache Angelegenheit, einen Anforderungshandler zu schreiben, der eine Anforderung an einen anderen Server über eine HTTP-Clientbibliothek sendet und dann diese Antwort zurückgibt.

# third-party HTTP client library 
import requests 

# assume that "app" below is your flask app, and that 
# "Response" is imported from flask. 

@app.route("/proxy-example") 
def proxy_example(): 
    r = requests.get("http://example.com/other-endpoint") 
    return Response(
     r.text 
     status=r.status_code, 
     content_type=r.headers['content-type'], 
    ) 

Dies wird jedoch nicht genau das gleiche Ergebnis erzielen, wie Sie es von einer clientseitigen Anfrage erwarten können. Da Ihr Server keine Cookies erkennen kann, die der Client-Browser für die Zielwebsite gespeichert hat, ist Ihre Proxy-Anfrage effektiv anonym und kann je nach Zielwebsite fehlschlagen oder Ihnen eine andere Antwort geben als gewünscht diese Ressource im Browser.

Wenn Sie eine Beziehung mit der URL eines Drittanbieters haben (dh wenn Sie eine Kontrolle über die Domäne haben oder mit den Personen arbeiten können, die sie ausführen), können sie im Browser unter CORS (d wird nur in modernen Browsern unterstützt) oder JSON-P (eine ältere Problemumgehung vor CORS).

Der Drittanbieter kann Ihnen auch Zugriff auf die gewünschten Daten an einem Endpunkt gewähren, der Anforderungen von anderen Servern akzeptiert und Ihnen einen Mechanismus zur Authentifizierung Ihrer App bereitstellt. Das gängigste Protokoll dafür ist OAuth.

+0

Haben Sie versucht, dieses Beispiel in einer laufenden Flask-App auszuführen? Wie andere Leute, die versuchen, Abrufe auszuführen, erhalte ich Fehler wie "requests.exceptions.InvalidSchema: Es wurden keine Verbindungsadapter für ... gefunden" (... == meine Ziel-URL). Ich habe verschiedene URLs ausprobiert, von http://myurl.com bis zu Dingen wie http: // localhost: 5000/myurl ... aber keine Anfrage. Und ich habe sogar versucht, einen rekursiven Aufruf der Route auszuführen, um zu sehen, ob 'requests.get()' funktionieren würde (und die Route erneut auslösen würde), aber auch URLs wie 'requests.get (" localhost: 5000/myroute ") tun rekursive Aufrufe nicht verursachen. Es scheint, als würden Anfragen einfach nicht funktionieren ... – JMM

0

Wie die anderen Antworten angegeben haben, wäre die Verwendung des Request-Moduls für Python der beste Weg, dies aus der Coding-Perspektive heraus anzugehen. Wie jedoch die erwähnten Kommentare (und der Grund, warum ich zu dieser Frage gekommen bin), kann dies einen Fehler ergeben, dass die Anfrage abgelehnt wurde. Dieser Fehler wird wahrscheinlich von SELinux verursacht.

Um zu überprüfen, ob dies das Problem ist zunächst sicher, dass SELinux mit diesem Befehl aktiviert machen wird:

sestatus 

Wenn ‚Current Mode‘ ist ‚Erzwingen‘, dann wird SELinux aktiviert.

Weiter, um die aktuellen Bool-Werte erhalten, die direkt mit diesem Befehl Apache gelten:

getsebool -a | grep httpd 

Suchen Sie nach der Einstellung ‚httpd_can_network_connect‘ das bestimmt, ob Apache erlaubt ist, TCP-Anfragen aus dem Netzwerk zu machen. Wenn es eingeschaltet ist, sind alle Apache-TCP-Anfragen erlaubt. Um sie zu aktivieren den folgenden Befehl als root:

setsebool -P httpd_can_network_connect 1 

Wenn Sie nur den Datenbankzugriff (Ich hatte dieses Problem vor, weshalb ich SELinux hier vermutet), dann wäre es wahrscheinlich besser sein, nur einschalten ‚httpd_cna_network_connect‘ .

Der Zweck dieser Richtlinie ist, dass, wenn ein Hacker Ihren Apache-Server entführen würde, sie nicht in der Lage wären, über den Server an den Rest Ihres internen Netzwerks zu gelangen.

Dies würde wahrscheinlich schon als Kommentar besser gewesen, aber ich habe nicht genug rep ..

Quellen: https://tag1consulting.com/blog/stop-disabling-selinux https://wiki.centos.org/TipsAndTricks/SelinuxBooleans

Verwandte Themen