Originally, I tried to post an ajax request from my client side to a third party url, but it seems that the browser have security issues with that. I thought about sending an ajax to the server side, from there to send a GET request to the third party, get the response and send it back to the client side. How can I do that with flask?
最初,我试图将ajax请求从客户端发送到第三方url,但似乎浏览器存在安全问题。我考虑过向服务器端发送ajax,从那里向第三方发送GET请求,获取响应并将其发送回客户端。我怎么用烧瓶来做呢?
3 个解决方案
#1
40
Install the requests
module (much nicer than using urllib2
) and then define a route which makes the necessary request - something like:
安装请求模块(比使用urllib2要好得多),然后定义发送必要请求的路由——如下所示:
import requests
from flask import Flask
app = Flask(__name__)
@app.route('/some-url')
def get_data():
return requests.get('http://example.com').content
Depending on your set up though, it'd be better to configure your webserver to reverse proxy to the target site under a certain URL.
但是,根据您的设置,最好将您的webserver配置为在某个URL下反向代理到目标站点。
#2
8
Flask alone does not have this capability, but it is a simple matter to write a request handler that makes a request to another server using an HTTP client library and then return that response.
Flask本身没有这个功能,但是编写一个请求处理程序(使用HTTP客户端库向另一个服务器发出请求,然后返回响应)是很简单的事情。
# 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'],
)
However, this will not achieve exactly the same result as you might expect from a client-side request. Since your server cannot "see" any cookies that the client browser has stored for the target site, your proxied request will be effectively anonymous and so, depending on the target site, may fail or give you a different response than you'd get requesting that resource in the browser.
但是,这并不能实现与客户端请求完全相同的结果。由于您的服务器不能“看到”客户机浏览器为目标站点存储的任何cookie,您的代理请求将是有效匿名的,因此,根据目标站点的不同,可能会失败或给您一个不同于在浏览器中请求该资源的响应。
If you have a relationship with the third-party URL (that is, if you control it or are able to work with the people who do) they can give access for cross-domain requests in the browser using CORS (which is only supported in modern browsers) or JSON-P (an older workaround that predates CORS).
如果你有一个与第三方的关系URL(也就是说,如果你控制它能够工作的人),他们可以在浏览器中访问跨域请求使用歌珥(在现代浏览器只支持)或JSON-P(早于歌珥的老方法)。
The third-party provider could also give you access to the data you want at an endpoint that is designed to accept requests from other servers and that provides a mechanism for you to authenticate your app. The most popular protocol for this is OAuth.
第三方提供程序还可以让您访问您想要的端点,该端点可以接受来自其他服务器的请求,并提供一种机制来验证您的应用程序。
#3
0
As the other answers have stated using the requests module for python would be the best way to tackle this from the coding perspective. However as the comments mentioned (and the reason I came to this question) this can give an error that the request was denied. This error is likely cause by SELinux.
如其他答案所述,使用python的请求模块将是从编码的角度解决这一问题的最佳方式。但是,正如所提到的评论(以及我之所以提到这个问题的原因),这可能会导致一个错误,即请求被拒绝。这个错误可能是SELinux导致的。
To check if this is the issue first make sure SELinux is enabled with this command:
要检查这是否是问题,首先要确保SELinux使用以下命令启用:
sestatus
If 'Current Mode' is 'enforcing' then SELinux is enabled.
如果“当前模式”是“强制”,则启用SELinux。
Next get the current bool values that apply directly to apache with this command:
接下来获取直接应用于apache的当前bool值:
getsebool -a | grep httpd
Look for the setting 'httpd_can_network_connect' this determines if apache is allowed to make TCP requests out to the network. If it is on then all apache TCP requests will be allowed. To turn it on run the following as root:
查找设置“httpd_can_network_connect”,它确定是否允许apache向网络发出TCP请求。如果它是on的,那么所有的apache TCP请求都将被允许。打开它运行如下作为根:
setsebool -P httpd_can_network_connect 1
If you only need database access (I had this problem before which is why I suspected SELinux here) then it would probably be better to only turn on 'httpd_cna_network_connect'.
如果您只需要数据库访问(我以前遇到过这个问题,这就是为什么我在这里怀疑SELinux),那么最好只打开“httpd_cna_network_connect”。
The purpose of this policy is that if a hacker was to hijack your apache server they would not be able to get out through the server to the rest of your internal network.
该策略的目的是,如果黑客劫持了您的apache服务器,那么他们就无法通过服务器向您的内部网络的其他部分发送信息。
This probably would've been better as a comment but I don't have enough rep..
这可能会更好,但我没有足够的代表。
Sources: https://tag1consulting.com/blog/stop-disabling-selinux https://wiki.centos.org/TipsAndTricks/SelinuxBooleans
来源:https://tag1consulting.com/blog/stop-disabling-selinux https://wiki.centos.org/TipsAndTricks/SelinuxBooleans
#1
40
Install the requests
module (much nicer than using urllib2
) and then define a route which makes the necessary request - something like:
安装请求模块(比使用urllib2要好得多),然后定义发送必要请求的路由——如下所示:
import requests
from flask import Flask
app = Flask(__name__)
@app.route('/some-url')
def get_data():
return requests.get('http://example.com').content
Depending on your set up though, it'd be better to configure your webserver to reverse proxy to the target site under a certain URL.
但是,根据您的设置,最好将您的webserver配置为在某个URL下反向代理到目标站点。
#2
8
Flask alone does not have this capability, but it is a simple matter to write a request handler that makes a request to another server using an HTTP client library and then return that response.
Flask本身没有这个功能,但是编写一个请求处理程序(使用HTTP客户端库向另一个服务器发出请求,然后返回响应)是很简单的事情。
# 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'],
)
However, this will not achieve exactly the same result as you might expect from a client-side request. Since your server cannot "see" any cookies that the client browser has stored for the target site, your proxied request will be effectively anonymous and so, depending on the target site, may fail or give you a different response than you'd get requesting that resource in the browser.
但是,这并不能实现与客户端请求完全相同的结果。由于您的服务器不能“看到”客户机浏览器为目标站点存储的任何cookie,您的代理请求将是有效匿名的,因此,根据目标站点的不同,可能会失败或给您一个不同于在浏览器中请求该资源的响应。
If you have a relationship with the third-party URL (that is, if you control it or are able to work with the people who do) they can give access for cross-domain requests in the browser using CORS (which is only supported in modern browsers) or JSON-P (an older workaround that predates CORS).
如果你有一个与第三方的关系URL(也就是说,如果你控制它能够工作的人),他们可以在浏览器中访问跨域请求使用歌珥(在现代浏览器只支持)或JSON-P(早于歌珥的老方法)。
The third-party provider could also give you access to the data you want at an endpoint that is designed to accept requests from other servers and that provides a mechanism for you to authenticate your app. The most popular protocol for this is OAuth.
第三方提供程序还可以让您访问您想要的端点,该端点可以接受来自其他服务器的请求,并提供一种机制来验证您的应用程序。
#3
0
As the other answers have stated using the requests module for python would be the best way to tackle this from the coding perspective. However as the comments mentioned (and the reason I came to this question) this can give an error that the request was denied. This error is likely cause by SELinux.
如其他答案所述,使用python的请求模块将是从编码的角度解决这一问题的最佳方式。但是,正如所提到的评论(以及我之所以提到这个问题的原因),这可能会导致一个错误,即请求被拒绝。这个错误可能是SELinux导致的。
To check if this is the issue first make sure SELinux is enabled with this command:
要检查这是否是问题,首先要确保SELinux使用以下命令启用:
sestatus
If 'Current Mode' is 'enforcing' then SELinux is enabled.
如果“当前模式”是“强制”,则启用SELinux。
Next get the current bool values that apply directly to apache with this command:
接下来获取直接应用于apache的当前bool值:
getsebool -a | grep httpd
Look for the setting 'httpd_can_network_connect' this determines if apache is allowed to make TCP requests out to the network. If it is on then all apache TCP requests will be allowed. To turn it on run the following as root:
查找设置“httpd_can_network_connect”,它确定是否允许apache向网络发出TCP请求。如果它是on的,那么所有的apache TCP请求都将被允许。打开它运行如下作为根:
setsebool -P httpd_can_network_connect 1
If you only need database access (I had this problem before which is why I suspected SELinux here) then it would probably be better to only turn on 'httpd_cna_network_connect'.
如果您只需要数据库访问(我以前遇到过这个问题,这就是为什么我在这里怀疑SELinux),那么最好只打开“httpd_cna_network_connect”。
The purpose of this policy is that if a hacker was to hijack your apache server they would not be able to get out through the server to the rest of your internal network.
该策略的目的是,如果黑客劫持了您的apache服务器,那么他们就无法通过服务器向您的内部网络的其他部分发送信息。
This probably would've been better as a comment but I don't have enough rep..
这可能会更好,但我没有足够的代表。
Sources: https://tag1consulting.com/blog/stop-disabling-selinux https://wiki.centos.org/TipsAndTricks/SelinuxBooleans
来源:https://tag1consulting.com/blog/stop-disabling-selinux https://wiki.centos.org/TipsAndTricks/SelinuxBooleans