8

SSL を終了するロード バランスの背後に Flask アプリケーションがあります。SSL が使用されていることを「検出」し、リクエスト オブジェクトを変更するコードがあります。

@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://')

次に、青写真ビュー機能があります。

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

この関数の出力は (/admin/login に移動すると) 常に https:// ではなく http:// になります (関数で変更されているはずですがbefore_request.

これを修正する方法についてのアイデアはありますか?

4

1 に答える 1

10

requestプロキシされたオブジェクトであることが判明しました。内部についてはわかりませんが、インポートごとに「リセット」されます。サブクラス化して問題を解決しました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
于 2013-11-07T17:25:45.357 に答える