python flask从http重定向到https

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32237379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 11:15:23  来源:igfitidea点击:

python flask redirect to https from http

pythonsslflask

提问by David Yuan

I have a website build using python3.4 and flask...I have generated my own self-signed certificate and I am currently testing my website through localhost.

我有一个使用 python3.4 和 Flask 构建的网站...我已经生成了自己的自签名证书,目前我正在通过 localhost 测试我的网站。

I am using the python ssl module along with this flask extension: https://github.com/kennethreitz/flask-sslify

我正在使用 python ssl 模块和这个烧瓶扩展:https: //github.com/kennethreitz/flask-sslify

context = ('my-cert.pem', 'my-key.pem')
app = Flask(__name__)
sslify = SSLify(app)

...

if __name__ == '__main__':
    app.debug = False
    app.run(
    host="127.0.0.1",
    port=int("5000"),
    ssl_context=context
)

This does not seem to be working however. I took a look in the sslify source code and this line does not seem to be working

然而,这似乎不起作用。我查看了 sslify 源代码,这行似乎不起作用

def init_app(self, app):
    """Configures the configured Flask app to enforce SSL."""
    app.before_request(self.redirect_to_ssl)
    app.after_request(self.set_hsts_header)

Specifically the function call to redirect_to_ssl (I added my own print statement under the redirect_to_ssl function and my statement was never printed)

特别是对redirect_to_ssl的函数调用(我在redirect_to_ssl函数下添加了我自己的打印语句,我的语句从未打印过)

def redirect_to_ssl(self):
    print("THIS IS WORKING")
    """Redirect incoming requests to HTTPS."""
    Should we redirect?
    criteria = [
        request.is_secure,
        current_app.debug,
        request.headers.get('X-Forwarded-Proto', 'http') == 'https'
    ]

    if not any(criteria) and not self.skip:
        if request.url.startswith('http://'):
            url = request.url.replace('http://', 'https://', 1)
            code = 302
            if self.permanent:
                code = 301
            r = redirect(url, code=code)
            return r

I am pretty new to python. Any ideas?

我对python很陌生。有任何想法吗?

回答by Kelly Keller-Heikkila

To me, it appears you're making it more complicated than it needs to be. Here is the code I use in my views.py script to force user to HTTPS connections:

对我来说,看起来你让它变得比它需要的更复杂。这是我在 views.py 脚本中用于强制用户进行 HTTPS 连接的代码:

@app.before_request
def before_request():
    if request.url.startswith('http://'):
        url = request.url.replace('http://', 'https://', 1)
        code = 301
        return redirect(url, code=code)

回答by tuned

The standard solution is to wrap the request with an enforce_ssldecorator that after checking some flags in the app configuration (flags you can set depending on your debugging needs) modifies the request's url with request.url.

标准的解决方案是使用enforce_ssl装饰器包装请求,在检查应用程序配置中的一些标志(您可以根据调试需要设置标志)后,将请求的 url 修改为request.url.

As it is written here.

正如这里所写。

You can modify the code to make it working with before_requestas suggested by @kelly-keller-heikkila

您可以before_request按照@kelly-keller-heikkila 的建议修改代码以使其正常工作

回答by Rodolfo Alvarez

According with the docs, after pip install Flask-SSLifyyou only need to insert the following code:

根据docs,之后pip install Flask-SSLify您只需要插入以下代码:

from flask import Flask
from flask_sslify import SSLify

app = Flask(__name__)
sslify = SSLify(app)

I have done it and it works very well. Am I missing something in the discussion ?

我已经做到了,而且效果很好。我在讨论中遗漏了什么吗?

回答by anulaibar

Thanks to answer from Kelly Keller-Heikkilaand comment by jaysqrdI ended up doing this in my Flask app:

由于从答案凯利·凯勒,Heikkila和评论通过jaysqrd我结束了我的瓶的应用程序这样做:

from flask import request, redirect
...

@app.before_request
def before_request():
    if not request.is_secure and app.env != "development":
        url = request.url.replace("http://", "https://", 1)
        code = 301
        return redirect(url, code=code)

I tried the flask_sslifysolution suggested by Rodolfo Alvarezbut ran into this issueand went with the above solution instead.

我尝试了Rodolfo Alvarezflask_sslify建议的解决方案,但遇到了这个问题,而是采用了上述解决方案。

The app.envcheck is there to let unit tests and local development run without https.

app.env检查是有让单元测试和地方发展不HTTPS运行。

回答by MohanBabu

I'm using cloud foundry python app which is behind a load balancer (like https://stackoverflow.com/users/5270172/kelly-keller-heikkilasaid) . This resolution helped me by adding (_external and _Scheme to the url_for function). https://github.com/pallets/flask/issues/773

我正在使用负载均衡器后面的云代工厂 python 应用程序(如https://stackoverflow.com/users/5270172/kelly-keller-heikkila说)。该解决方案通过添加 (_external 和 _Scheme 到 url_for 函数) 来帮助我。https://github.com/pallets/flask/issues/773

回答by Eyal Levin

The Flask Security Guiderecommends using Flask-Talisman.

瓶安全指南建议使用瓶,护符

$ pip install flask-talisman

Usage example:

用法示例:

from flask import Flask
from flask_talisman import Talisman

app = Flask(__name__)
Talisman(app)

It forces HTTPSby default (from the README):

HTTPS默认强制(来自自述文件):

force_https, default True, forces all non-debug connects to https.

force_https, 默认True, 强制所有非调试连接到https.



Personally, I got some errors relating to CSP (Content Security Policy) which I disabled with:

就我个人而言,我遇到了一些与我禁用的 CSP(内容安全策略)相关的错误:

Talisman(app, content_security_policy=None)

But use this at your own risk :)

但使用它需要您自担风险:)

回答by Wietze

I use a simple extra app that runs on port 80 and redirect people to https:

我使用一个简单的额外应用程序,它在端口 80 上运行并将人们重定向到 https:

from flask import Flask,redirect

app = Flask(__name__)

@app.route('/')
def hello():
    return redirect("https://example.com", code=302)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80)

回答by edW

Here is a flask solution if you are on aws and behind a load balancer. Place it in your views.py

如果您在 aws 上并在负载均衡器后面,这是一个烧瓶解决方案。把它放在你的 views.py 中

@app.before_request
def before_request():
    scheme = request.headers.get('X-Forwarded-Proto')
    if scheme and scheme == 'http' and request.url.startswith('http://'):
        url = request.url.replace('http://', 'https://', 1)
        code = 301
        return redirect(url, code=code)

回答by Evan G

I ran into the same solution running a Flask application in AWS Elastic Beanstalk behind a load balancer. The following AWS docs provided two steps to configure the environment for http redirects: https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.htmlFollowing both steps fixed my issue.

我遇到了在负载均衡器后面的 AWS Elastic Beanstalk 中运行 Flask 应用程序的相同解决方案。以下 AWS 文档提供了两个步骤来配置 http 重定向的环境:https: //docs.aws.amazon.com/elasticbeanstalk/latest/dg/configuring-https-httpredirect.html按照这两个步骤解决了我的问题。

One thing to note is that you'll have to create the .ebextenions folder at the root level of your application source bundle and add the config file to that .ebextensions folder. The readme here: https://github.com/awsdocs/elastic-beanstalk-samplesexplains this in a bit more detail.

需要注意的一件事是,您必须在应用程序源包的根级别创建 .ebextensions 文件夹,并将配置文件添加到该 .ebextensions 文件夹。这里的自述文件:https: //github.com/awsdocs/elastic-beanstalk-samples更详细地解释了这一点。

回答by Maximilian Burszley

An alternative to the other answers that I've been able to use with great success:

我已经能够成功使用的其他答案的替代方案:

from http import HTTPStatus
from typing import Optional

from flask import Response, redirect, request, url_for


def https_redirect() -> Optional[Response]:
    if request.scheme == 'http':
        return redirect(url_for(request.endpoint,
                                _scheme='https',
                                _external=True),
                        HTTPStatus.PERMANENT_REDIRECT)


# ..

if app.env == 'production':
    app.before_request(https_redirect)

# ..