问题
我为几个简单的志愿者组织工作,帮助管理和运行活动,但我们需要一个系统来跟踪人们的工作时间,以获得酬金和生产力跟踪。我认为这将是一个学习网络开发的好机会,并开始使用flask应用程序,因为它显然比django更简单,我不知道JavaScript。部署应用程序修复bug等,但是现在有人在提交登录表单后用this picture登录后回来了。
“缺少错误的请求CSRF令牌”。
“错误的请求CSRF令牌不匹配”。
“错误的请求CSRF令牌已过期”。
这些是我设法得到的错误消息,除非我实施错误,否则没有在线解决方案可以为我修复它们。我甚至没有在我的gunicorn日志中得到错误消息,我只是加载了那个图像。
经过这么长时间的调试,让它工作并自豪地展示它,现在它做到了这一点,所以也许是那些有偏见的挫折眼镜阻止了我明智地找到解决方案
代码
我有我的隐藏标记的地方,所以csrf不应该错过/webapp/website/templates/login.html
<body>
{%extends 'base.html'%}
{% block content %}
<div class="shadow p-3 mb-5 bg-body rounded">
<h3 align="center">Login</h3>
<form method="POST">
{{ form.hidden_tag() }}
{{ form.email.label(class='form-label')}}
{{ form.email(class='form-control')}}
<br/>
{{ form.password.label(class='form-label')}}
{{ form.password(class='form-control')}}
<br/>
{{ form.submit(class='btn btn-danger')}}
</form>
</div>
{% endblock %}
</body>
</html>
字符串
.env
SECRET_KEY='iremovedtheactualone'
DEV_DATABASE_URI='mysql+pymysql://root:root@localhost/main'
PROD_DATABASE_URI='mysql+pymysql://user:password@ip/db'
SERVER_NAME='websitename.com'
型
www到非www的nginx重定向不工作,我的应用程序在www上不工作是一个完全不同的问题,我的一个朋友概述了here/webapp/website/config.py
个
from os import environ, path
from dotenv import load_dotenv
DB_NAME = "main"
class Config:
"""Base config."""
#SESSION_COOKIE_NAME = environ.get('SESSION_COOKIE_NAME')
MAX_CONTENT_LENGTH = 16*1000*1000
RECEIPT_FOLDER = '..\\assets\\receipts'
UPLOAD_EXTENSIONS = ['.jpg', '.png', '.pdf']
STATIC_FOLDER = 'static'
TEMPLATES_FOLDER = 'templates'
SESSION_COOKIE_SECURE = True
class ProdConfig(Config):
basedir = path.abspath(path.dirname(__file__))
load_dotenv('/home/sai/.env')
env_dict = dict(environ)
FLASK_ENV = 'production'
DEBUG = False
TESTING = False
SQLALCHEMY_DATABASE_URI = environ.get('PROD_DATABASE_URI')
SECRET_KEY = environ.get('SECRET_KEY')
SERVER_NAME = environ.get('SERVER_NAME')
...
型/webapp/website.__init__.py
个
def create_app(name):
#Flask Instance
app = Flask(__name__)
app.config.from_object(config.ProdConfig)
if name != '__main__':
gunicorn_logger=logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
db.init_app(app)
migrate.init_app(app, db)
csrf.init_app(app)
...
型/webapp/website.auth.py
个
@auth.route('/login', methods=['GET', 'POST'])
def login():
current_app.logger.info('enter login')
...
if form.validate_on_submit():
current_app.logger.info('enter submit')
...
user = Users.query.filter_by(email=email).first()
if user:
current_app.logger.info('enter user')
if check_password_hash(user.password_hash, password):
current_app.logger.info('enter password')
flash('Logged in successfully!', category='success')
login_user(user, remember=True)
form.email.data = ''
form.password.data = ''
#Default
return redirect('/shift_add')
# Method Two
next = request.args.get('next')
#current_app.logger.info(next)
#if not is_safe_url(next):
# return abort(400)
#else:
# return redirect(next or url_for('views.home'))
# Method Three
#next_url = request.form.get("next")
#if next_url:
# return redirect(next_url)
#return redirect(url_for('views.home') or next)
# Method Four
# return redirect(str(request.args.get("next")) or "/shift_add")
else:
...
else:
...
...
else:
current_app.logger.info('errors: ')
current_app.logger.info(form.errors)
return render_template('/user/login.html', form=form)
型
主要问题
我如何解决CSRF有时丢失或过期或不匹配的问题。这些错误都不会在我的日志中引发任何问题,除非我没有正确显示,但我不知道为什么每个错误都会发生。现在我的Chrome浏览器给我令牌丢失,Firefox给我过期,iPhone上的Safari给我不匹配。
同样令人信服的是,我如何配置CSRF错误?我错过了什么?我想学习的不仅仅是如何解决这些问题,而是为什么它们会发生,以及前进的最佳实践。谢谢!
尝试解决方案
Clearing cookies解决CSRF令牌不匹配。我尝试在Chrome上以隐身模式运行网站,我得到的CSRF令牌丢失,这是我的Chrome问题。Firefox(我的问题是它说过期),但在隐身模式下也说令牌丢失。
Apparently a bug in webkit browsers我没有运行Docker,也许这个解决方案只是超出了我的理解范围。
Too large of info being sent through不是这种情况,因为我以前成功登录过,我没有发送任何这么大的东西。
3条答案
按热度按时间mwecs4sa1#
This答案救了我的命,我发现它只在这里经过几天的研究。
cvxl0en22#
你总是可以使用csrf_exempt装饰器。
这不是一个好的做法,
nwlqm0z13#
当我在Gunicorn上启用多个worker时,我开始得到错误
The CSRF token is invalid
。我认为对我来说,问题是我的SECRET_KEY
在每个worker中随机生成。所以CSRF只有在我的请求由同一个worker处理时才有效。定义一个非随机的SECRET_KEY
对我来说很有效。