我希望能够检测用户自上次登录 Flask 站点后是否关闭了浏览器。我读过 Flask 会话应该在关闭浏览器时过期,但据我所知,会话数据存储在服务器上,并且在浏览器会话中持续存在。如何在用户关闭浏览器时清除所有会话数据?
mainapp.py:
@mainapp.route('/')
def home():
if 'user_name' in session:
logger.debug( 'Logged in as {0}'.format(escape(session['user_name'])))
return render_template('home.html')
用户视图.py:
@userviews.route("/login", methods=["GET", "POST"])
def login():
form = LoginForm(request.form)
if form.validate_on_submit():
#get user from db
session['user_name'] = user.user_name
setup.py:
app.secret_key = 'somethingreallysecret'
因为flask session使用了cookies,所以即使用户关闭了窗口,数据也会被持久化。您可以使用 Flask-SocketIO 跟踪关闭窗口的使用情况。
如果你想从会话中删除特定的密钥:
from flask import session
from flask_socketio import SocketIO, emit
from flask.ext.login import current_user, logout_user
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socketio = SocketIO(app)
@socketio.on('disconnect')
def disconnect_user():
logout_user()
session.pop('yourkey', None)
似乎与 vanilla Flask 相反,Flask-session 中打开的会话默认是永久的,来自文档:
默认情况下,Flask-Session 中的所有非空会话都是永久性的。
所以也许尝试设置 SESSION_PERMANENT=False?
根据文档(https://flask.palletsprojects.com/en/1.1.x/api/#flask.session.permanent):
永久:
"如果设置为 True,会话将存在 permanent_session_lifetime 秒。默认值为 31 天。如果设置为 False(默认值),会话将在用户关闭浏览器时被删除。"
在您设置会话变量的代码块中包括这一行:
session.permanent = False
例如
@app.route("/login", methods=["GET", "POST"])
def login() -> "html":
if request.method == "GET":
return render_template(
"login.html",
)
else:
# Process login form...
# ...then set session variable
session.permanent = False
session["username"] = "some value"
return render_template(
"some_secure_page.html",
)
正如 Amin 所回答的,您可以使用 Flask-SocketIO,但正如您提到的那样,性能会受到影响。
你说“据我所知,会话数据存储在服务器上”,但从那句话来看,你不清楚你是使用 Flask 的服务器端会话扩展(例如 Flask-Session)还是假设会话数据存储在服务器上,但实际上,您使用客户端的 Flask 内置会话类。
如果您使用客户端会话,则会话信息存储在 Web 浏览器的 cookie 中。如果是
session.permanent = False
(这是默认设置),那么当用户关闭浏览器时会话将被删除(由 Dan 分享)。但是,如果浏览器启动设置是“打开以前的窗口和选项卡”(在 Firefox 中)/“从以前的会话中打开选项卡”(在 MS Edge 中)等,则网络浏览器中的会话 cookie 不会被删除,而是会保留(所以当你再次打开浏览器时,会话仍然存在)。
Flask-SocketIO 的潜在替代解决方案(由 Jordan Bonser 在 https://www.bonser.dev/flask-session-timeout.html 提供)可能是使用
before_request
函数并将 permanent_session_lifetime
设置为一些合理的value 和 session.modified = True
因此每次有用户交互时都会重置会话生命周期计时器。会话数据在定义的用户不活动时间后被清除。
@app.before_request
def before_request():
flask.session.permanent = True
app.permanent_session_lifetime = datetime.timedelta(minutes=20)
flask.session.modified = True