Flask如何实现用户登录后持久保持登录状态(关闭浏览器不失效)
你项目里用的Flask-Login本身就是基于Flask session实现身份认证的:login_user()会自动把用户凭证加密存到session里,current_user的加载、is_authenticated状态判断组件都已经封装完成,不需要手动往session写用户id、自己写认证判断逻辑。默认配置下关浏览器就退出登录,本质是生成的session cookie是会话级的,浏览器关闭就自动删除,改几行配置就能实现持久化。
具体配置步骤
1. 修改Flask session基础配置
找到你项目里创建Flask app实例的位置(对应代码里from yff import app的yff包初始化文件,一般是__init__.py),在app创建完成后添加以下配置:
# 密钥为session加密必填项,生产环境用足够长的随机字符串,不要对外泄露 app.config['SECRET_KEY'] = '替换为你自己生成的随机字符串' # 开启永久session,默认值为False时session cookie会在浏览器关闭时自动删除 app.config['SESSION_PERMANENT'] = True # 设置session整体有效期,单位为秒,示例为30天有效期,可按需调整时长 app.config['PERMANENT_SESSION_LIFETIME'] = 30 * 24 * 60 * 60
2. 补全Flask-Login核心配置
还是在app初始化的位置,找到初始化LoginManager的代码块,补全以下配置:
from flask_login import LoginManager login_manager = LoginManager(app) # 会话保护等级,设为strong会记录用户IP、浏览器UA特征,异常访问时自动清除登录态,需要宽松规则可设为basic login_manager.session_protection = "strong" # 记住登录状态的cookie有效期,和上面的session有效期保持一致即可 login_manager.remember_cookie_duration = 30 * 24 * 60 * 60 # 禁止JS读取登录cookie,防范XSS攻击窃取登录凭证,建议开启 login_manager.remember_cookie_httponly = True # 站点为HTTPS协议时打开下面的配置,HTTP站点不要开启 # login_manager.remember_cookie_secure = True
必须确认你写了user_loader回调函数,这是Flask-Login能从session存储的用户id加载出current_user对象的核心,没写的话直接补在LoginManager初始化代码下方:
@login_manager.user_loader def load_user(user_id): # 对应你的User模型主键查询逻辑即可 return User.query.get(int(user_id))
配置完这个回调,每次请求进来Flask-Login会自动从session里取出存储的用户id,查询到对应的用户实例挂载到current_user变量上,current_user.is_authenticated的返回值会自动判断,不需要额外写判断逻辑。
3. 调整登录接口的remember参数
你现有登录路由里的代码是login_user(user, remember=form.remember.data),逻辑是只有用户勾选表单里的“记住我”选项才会生成持久化cookie:
- 如果需要所有用户登录后默认持久化、关浏览器不失效,直接把这行改成
login_user(user, remember=True)即可 - 如果要保留用户自主选择是否记住登录状态的交互,这行代码不需要修改,前面的配置生效后,用户勾选“记住我”登录的场景下,关闭浏览器也不会丢失登录态
4. 登出逻辑不需要修改
你现有代码里的logout_user()方法会自动清除session里的登录凭证和对应remember cookie,直接复用即可。
配置上线注意事项:
- 生产环境的
SECRET_KEY不要硬编码在代码里,尽量从环境变量读取,一旦泄露攻击者可以伪造任意用户的登录session- 上线后不要随意更换
SECRET_KEY,更换后所有现存用户的session都会失效,需要重新登录- 登录有效期不要设置过长,一般7-30天比较合理,过长会提升凭证泄露后的安全风险
配置完成后重启服务即可生效,用户登录后只要没到设置的过期时间,哪怕关闭浏览器重新打开站点,current_user.is_authenticated都会返回True,模板里和用户绑定的个性化内容可以正常渲染。
内容的提问来源于stack exchange,提问作者Addy

