在Flask中突变request.base_url [英] Mutating request.base_url in Flask

查看:237
本文介绍了在Flask中突变request.base_url的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Flask应用程序,负载平衡终止SSL。我有代码,检测SSL使用时,并改变请求对象:

pre $ app $ be $ request
def before_request():
x_forwarded_proto = request.headers.get('X-Forwarded-Proto')
if x_forwarded_proto =='https':
request.url = request.url.replace ('http://','https://')
request.url_root = request.url_root.replace('http://','https://')
request.host_url = request.host_url.replace('http://','https://')

然后,我有一个蓝图视图功能:

  admin = Blueprint('admin',__name__,url_prefix ='/ admin')
@ admin.route('/ login')
def login():
print request.url

这个函数的输出是(当我去/ admin / login时)始终是http://而不是https://(尽管它应该在 before_request 函数。



关于如何解决这个问题的任何想法?

解决方案

结果请求是一个代理对象。我不确定内部结构,但每次导入都会重置。我通过继承 Request

  class ProxiedRequest(Request): 
def __init __(self,environ,populate_request = True,shallow = False):
super(Request,self).__ init __(environ,populate_request,shallow)
#支持SSL终止。如果SSL终止,则将Flask中的host_url变为使用https://
#。
x_forwarded_proto = self.headers.get('X-Forwarded-Proto')
if x_forwarded_proto =='https':
self.url = self.url.replace('http:/ /','https://')
self.host_url = self.host_url.replace('http://','https://')
self.base_url = self.base_url。 replace('http://','https://')
self.url_root = self.url_root.replace('http://','https://')

app = Flask(__ name__);
app.request_class = ProxiedRequest


I have a Flask application behind a Load balance that terminates SSL. I have code that "detects" when SSL is being used and mutates the request object:

@app.before_request
def before_request():
    x_forwarded_proto = request.headers.get('X-Forwarded-Proto')
    if  x_forwarded_proto == 'https':
        request.url = request.url.replace('http://', 'https://')
        request.url_root = request.url_root.replace('http://', 'https://')
        request.host_url = request.host_url.replace('http://', 'https://')

I then have a blueprint view function:

admin = Blueprint('admin', __name__, url_prefix='/admin')
@admin.route('/login')
def login():
    print request.url

The output of this function is (when I go to /admin/login) is always http:// instead of https:// (even though it should have been mutated in the before_request function.

Any ideas on how I can fix this?

解决方案

Turns out request is a proxied object. I'm not sure of the internals but it's "reset" on each import. I solved the issue by subclassing Request

class ProxiedRequest(Request):
    def __init__(self, environ, populate_request=True, shallow=False):
        super(Request, self).__init__(environ, populate_request, shallow)
        # Support SSL termination. Mutate the host_url within Flask to use https://
        # if the SSL was terminated.
        x_forwarded_proto = self.headers.get('X-Forwarded-Proto')
        if  x_forwarded_proto == 'https':
            self.url = self.url.replace('http://', 'https://')
            self.host_url = self.host_url.replace('http://', 'https://')
            self.base_url = self.base_url.replace('http://', 'https://')
            self.url_root = self.url_root.replace('http://', 'https://')

app = Flask(__name__);
app.request_class = ProxiedRequest

这篇关于在Flask中突变request.base_url的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆