Flask CSRF会话令牌丢失

时间:2018-07-17 03:17:16

标签: session flask csrf

目标

我正在尝试在浏览器关闭和有时间限制的会话上实现会话终止/终止。我的解决方法需要app.permanent = False。这样,当关闭浏览器时,会话将终止。最重要的是,我还想应用限时会话。我的计划是在session['expiry'] = 2018-07-21 函数中执行before_request,并在会话过期时终止会话。

问题

我面临的问题是,当我尝试登录(当前使用开箱即用的烧瓶)时,出现400错误CSRF session token is missing。我已经尝试过{{ form.hidden_tag() }}, {{ form.csrf_token }},但似乎无济于事。仅当我移除csrf=CSRFProtect(app)时,它才起作用。我使用SQLAlchemySessionInterface使用Flask session_store实现了服务器端会话。

问题

  1. 是否有可能一起实现在浏览器关闭和有时间限制的会话时终止会话?如果可能的话,除了上述内容外,还有其他其他方法吗? (也尝试了JS onunload)。

  2. 关于缺少CSRF会话令牌的情况有什么想法?我认为它与CSRF令牌丢失有所不同,并且Google搜索返回的内容不多。

最小化代码

查看-login_view.py

from app import app
from flask import render_template, redirect
from flask_login import current_user
from flask_security import login_user, current_user
from login_form import LoginForm

@app.route('/login_test', methods=['GET', 'POST'])
def login_test():
    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):
            return redirect(url_for('login'))
        login_user(user)
        return redirect(url_for('main_bp.index_entry'))
    return render_template('login_test.html', title='Sign In', form=form)

login_form.py

from flask_wtf import FlaskForm
from wtforms import StringField, validators, PasswordField

# bare minimum of form class for testing

class LoginForm(FlaskForm):

    email = StringField('Email', [validators.DataRequired()])
    password = PasswordField('Password', [validators.DataRequired()])

HTML-login_test.html

<form action="{{ url_for('.login_test') }}" method="POST" name="user_login" autocomplete="off">


    {{ form.hidden_tag() }}


    {{ form.email(class_='form-control login_form', placeholder='Email (Required)') }}


    {{ form.password(class_='form-control login_form', placeholder='Password (Required)') }}


    <button type="submit">Submit</button>

</form>

app / __ init __。py

from flask import Flask
from flask_wtf.csrf import CSRFProtect
from flask_sessionstore import Session
from flask_sqlalchemy import SQLAlchemy
from flask_sessionstore import Session

app = Flask(__name__, static_folder='static', instance_relative_config=True)
app.config.from_pyfile('dev_app_config.py') 
db = SQLAlchemy(app)
app.config['SESSION_SQLALCHEMY'] = db
session = Session(app)
csrf = CSRFProtect(app)
# session.app.session_interface.db.create_all()

run.py

以下声明session.permanent = False无效,session.permanent仍设置为True。我只是显示before_request,因为它似乎是声明session.permanent的最常用的方法。

from app import app, session
@app.before_request
def make_session_permanent():
    session.permanent = False

instance / dev_app_config.py

我已经在应用程序的配置中声明了session.permanent,而不是在before_request之上,并且这样做实际上使session.permanent变为False

SECRET_KEY = 'asdf3333dsf....manymore'
WTF_CSRF_ENABLED = True
SESSION_PERMANENT = False
SESSION_COOKIE_DOMAIN = "127.0.0.1:5000"

0 个答案:

没有答案