python - 使用 nginx 烧瓶“redirect(url_for)”和“@login_required”错误
问题描述
我制作了一个托管在我的树莓派上的网络应用程序,我正试图从互联网上访问它。我正在使用 Dataplicity ( https://docs.dataplicity.com/docs/host-a-website-from-your-pi ) 使用 nginx 访问我的服务器。
在本地,一切正常。我会启动应用程序
flask run --host=0.0.0.0 --port=8000
使用端口 8000 或 80 在浏览器中转到我的 pi 地址,并成功获取我的应用程序的主页。在此之前,该过程同样适用于 dataplicity。
当我调用 redirect(url_for) 函数(包括@login_required)时,问题就出现了。一旦我通过 dataplicity 调用它,我就会得到“503 服务暂时不可用”。
当我在本地工作时(或在外部使用端口转发 -> 这让我认为问题出在 Dataplicity 和 nginx 上),当我尝试访问我的 /camera 视图功能而不先登录到应用程序时,我看到以下 GET 请求:
127.0.0.1 - - [07/May/2019 22:27:47] "GET /camera HTTP/1.0" 302 -
127.0.0.1 - - [07/May/2019 22:27:47] "GET /login?next=%2Fcamera HTTP/1.0" 200 -
当我尝试通过 dataplicity 访问它时,我只得到:
127.0.0.1 - - [07/May/2019 22:28:37] "GET /camera HTTP/1.0" 302 -
: "GET /login?next=%2Fcamera HTTP/1.0" 200 - 不存在。
如果这有帮助,dataplicity 中的每个 url 都显示为 https,除非我点击了 redirect(url_for) 或 @login_requested 函数,否则它会变成 http。
我尝试了在 Stack Overflow 上找到的几种不同的 nginx 配置,还尝试通过阅读文档对它们进行一些调整。这是徒劳的。我不会分享它们,因为我尝试的所有变化都导致相同的效果。
这是我的实际 nginx 配置:
server {
listen 80 ;
server_name _;
access_log /var/log/app_access.log;
error_log /var/log/app_error.log;
location / {
proxy_pass http://localhost:8000;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这是我的应用程序中的重要代码:
@app.route("/")
def index():
return render_template('index.html', title='Cat')
@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect(url_for('index'))
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user is None or not user.check_password(form.password.data):
flash('Invalid username or password')
return redirect(url_for('login'))
login_user(user, remember=form.remember_me.data)
next_page = request.args.get('next')
if not next_page or url_parse(next_page).netloc != '':
next_page = url_for('index')
return redirect(next_page)
return render_template('login.html', title='Sign In', form=form)
@app.route("/camera")
@login_required
def stream():
templateData = {
'title' : "Stream"
}
return render_template('camera.html', **templateData)
我希望在外部获得与本地获得相同的体验(通过 dataplicity,因为我不喜欢打开端口的想法)。也就是说,每次我被重定向时都能够使用我的“登录”视图功能而不会遇到错误。
更新:
我的应用程序终于可以正常运行了。我认为答案是 Gunicorn。我有以下supervisor
文件,我几乎没有测试过,因为我没有从中得到任何明确的反馈:
[program:app]
command=/var/www/html/app/sandbox/bin/gunicorn -b localhost:8000 -w 4 ...
directory=/var/www/html/app/
user=pi
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
今天试了很多次,重新加载的时候app就可以正常使用了supervisorctl
。我仍然需要找出是什么让这个特定的 nginx 配置只在 Gunicorn 运行时才起作用。
flask run --host=0.0.0.0 --port=8000
仍然无法正常工作。
gunicorn -b 0.0.0.0:8000 -w 4 app:app
正在工作中。
解决方案
推荐阅读
- typescript - 如何告诉 Typescript 检查 object[key] 是否属于某种类型?
- android - 领域迁移。如何更改列表类型?
- python - IrNet 实现 - 如何为 py 程序提供所需的参数
- python-3.x - 使用 python 生成裁剪图像时出错
- servicenow - ServiceNow 使用 REST API 创建更改请求
- javascript - 如何通过复选框或切换打开/关闭特定的 Javascript 脚本?
- sql - 带有 MAX DATE 和 Join 语句的 SQL 请求
- javascript - 使用通用方法捕获使用扩展名输入注册表单的用户名和密码
- c# - 如何在 Visual Studio 中解决此错误:无法将类型“字符串”隐式转换为“System.Collections.Generic.List”
' - javascript - 当同一文件夹中有多个 JavaScript 时,如何指定要运行的脚本?