Bla*_*ise 40 python url-routing werkzeug flask
我url_for用户在用户注销时生成重定向网址.
url_for
但是,当我将页面更改为https连接时,url_for仍然会给我http.
我想明确要求在网址的开头url_for添加https.
你能指点我怎么改变它吗?我看看Flask的文档,没有运气.
谢谢.
Mar*_*zer 50
使用Flask 0.10,可以获得比包装更好的解决方案url_for.如果查看https://github.com/mitsuhiko/flask/commit/b5069d07a24a3c3a54fb056aa6f4076a0e7088c7,_scheme则添加了一个参数.这意味着您可以执行以下操作:
url_for('secure_thingy',
_external=True,
_scheme='https',
viewarg1=1, ...)
Run Code Online (Sandbox Code Playgroud)
_scheme设置URL方案,生成一个https://..代替的URL http://.然而,在默认情况下只瓶生成路径(无需主机或方案),所以你需要包括_external=True从去/secure_thingy到https://example.com/secure_thingy.
但是,请考虑将您的网站设为仅限HTTPS.您似乎只尝试为少数"安全"路由部分强制执行HTTPS,但如果链接到安全页面的页面未加密,则无法确保不更改您的https-URL.这类似于混合内容.
ald*_*del 28
如果您想影响所有服务器生成的URL(url_for和redirect)的URL方案,而不是必须设置_scheme每次调用,似乎"正确"的答案是使用WSGI中间件,如下面的代码片段:http:// flask.pocoo.org/snippets/35/
(这个Flask bug似乎证实了这是首选方式.)
基本上,如果您的WSGI环境有environ['wsgi.url_scheme'] = 'https',那么url_for将生成https:URL.
我正在获取http://URL,url_for因为我的服务器部署在Elastic Beanstalk负载均衡器后面,后者通过常规HTTP与服务器通信.我的解决方案(特定于Elastic Beanstalk)就像这样(从上面链接的代码段中简化):
class ReverseProxied(object):
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
scheme = environ.get('HTTP_X_FORWARDED_PROTO')
if scheme:
environ['wsgi.url_scheme'] = scheme
return self.app(environ, start_response)
app = Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)
Run Code Online (Sandbox Code Playgroud)
特定于Elastic Beanstalk的部分是HTTP_X_FORWARDED_PROTO.其他环境可以通过其他方式确定外部URL是否包含https.如果您只想使用HTTPS,则可以无条件设置environ['wsgi.url_scheme'] = 'https'.
PREFERRED_URL_SCHEME不是这样做的方式.只要请求正在进行中,它就会被忽略.
daj*_*obe 25
我用url_forarg 尝试了接受的答案,但我发现使用PREFERRED_URL_SCHEMEconfig变量更容易,并将其设置为https:
app.config.update(dict(
PREFERRED_URL_SCHEME = 'https'
))
Run Code Online (Sandbox Code Playgroud)
因为您不必将其添加到每个url_for呼叫.
Tim*_*nin 14
如果您通过代理访问您的网站,那么Flask会正确地检测该方案HTTP.
Browser -----HTTPS----> Reverse proxy -----HTTP----> Flask
Run Code Online (Sandbox Code Playgroud)
最简单的解决方案是配置代理以设置X-Forwarded-Proto标头.Flask将自动检测此标头并相应地管理方案.代理设置部分下的Flask文档中有更详细的说明.例如,如果使用Nginx,则必须在location块中添加以下行.
proxy_set_header X-Forwarded-Proto $scheme;
Run Code Online (Sandbox Code Playgroud)
正如其他提到的,如果您无法更改代理的配置,您可以使用werkzeug ProxyFix或构建您自己的修补程序,如文档中所述:http://flask.pocoo.org/docs/0.12/deploying/ WSGI-独立/#代理设置
小智 9
对于最近到这里的人来说,有一个官方的 uwsgi 修复程序: /sf/answers/1645327911/
FWIW 这对我来说仍然不起作用,因为标头没有正确设置,所以我增强了 ReversedProxied 中间件以更喜欢 https(如果这样找到的话):
class ReverseProxied(object):
"""
Because we are reverse proxied from an aws load balancer
use environ/config to signal https
since flask ignores preferred_url_scheme in url_for calls
"""
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
# if one of x_forwarded or preferred_url is https, prefer it.
forwarded_scheme = environ.get("HTTP_X_FORWARDED_PROTO", None)
preferred_scheme = app.config.get("PREFERRED_URL_SCHEME", None)
if "https" in [forwarded_scheme, preferred_scheme]:
environ["wsgi.url_scheme"] = "https"
return self.app(environ, start_response)
Run Code Online (Sandbox Code Playgroud)
称为:
app = flask.Flask(__name__)
app.wsgi_app = ReverseProxied(app.wsgi_app)
Run Code Online (Sandbox Code Playgroud)
这样,如果您明确设置了环境变量“PREFERRED_URL_SCHEME”,或者 nginx/etc/proxy 设置了 X_FORWARDED_PROTO,它就会做正确的事情。
_scheme每次url_for()通话设置都非常繁琐,PREFERRED_URL_SCHEME似乎无法正常工作.但是,如果请求的假设方案处于WSGI级别,则可能会成功说服Flask始终构建HTTPS URL:
def _force_https(app):
def wrapper(environ, start_response):
environ['wsgi.url_scheme'] = 'https'
return app(environ, start_response)
return wrapper
app = Flask(...)
app = _force_https(app)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22132 次 |
| 最近记录: |