目标
我正在尝试在浏览器关闭和有时间限制的会话上实现会话终止/终止。我的解决方法需要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实现了服务器端会话。
问题
是否有可能一起实现在浏览器关闭和有时间限制的会话时终止会话?如果可能的话,除了上述内容外,还有其他其他方法吗? (也尝试了JS onunload)。
关于缺少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"