0
点赞
收藏
分享

微信扫一扫

从零开始构建报警中心:part09 使用flask-login实现用户登入登出

暮晨夜雪 2023-12-20 阅读 55


使用flask构建一个WEB管理系统,肯定要有登入登出需求的。这里使用flask的一个扩展flask-login来实现这个功能。

Flask-Login 是 Flask 中一个用于处理用户登录状态的扩展,它简化了用户认证的处理。它可以轻松地集成到 Flask 网站中,并提供了处理用户会话、保护路由等功能。

写在前面的话

在本示例中,并没有使用前文数据模型中的Account模型作为用户账号,同样的也没有将此模型作为flask-login的账号,因为在设计之初就将账号功能接入了已有的统一登录中。具体会在下一篇文档中详解。


Flask-Login的使用

Flask-Login 的主要功能:

  1. 用户会话管理: 管理用户的登录状态,使得用户在登录后可以访问受保护的视图,而未登录用户将被重定向到登录页面。
  2. 保护路由: 通过 @login_required 装饰器,可以轻松保护需要用户登录才能访问的路由。
  3. 当前用户对象: 提供一个 current_user 对象,可以方便地访问当前登录的用户对象。
  4. 记住我功能: 支持"记住我"功能,使用户在关闭浏览器后仍然保持登录状态。

初始化LoginManager

首先要初始化Flask-Login。在Flask应用中初始化LoginManager

app = Flask(__name__, template_folder="templates")
login_manager = LoginManager(app)  # Setup a Flask-Login Manager

创建用户模型

创建一个用户模型,并确保它包含一个唯一的标识符,例如用户的 ID,这里

class User:
    def __init__(self, user_id):
        self.id = user_id

加载用户回调函数

这里使用redis存储用户信息。

# 用户加载函数
@login_manager.user_loader
def load_user(user_id):
    return User(user_id)

Flask-Login配置项

Flask-Login 提供了一系列的配置项,你可以通过配置 LoginManager 对象的属性来定制其行为。以下是一些常见的 Flask-Login 配置项:

  1. login_view 设置登录页面的端点名称。当用户需要登录时,Flask-Login 会重定向到这个页面。默认值为 None,表示未配置登录页面,此时会返回 401 Unauthorized 错误。

login_manager.login_view = 'login'

  1. login_messagelogin_message_category 分别设置登录提示消息和消息的类别。当用户需要登录时,可以通过这两个配置项设置登录提示消息。

login_manager.login_message = '请先登录'
login_manager.login_message_category = 'info'

  1. login_message_fallback 设置登录提示消息的备用消息,当当前会话中不存在消息时使用。默认为 None

login_manager.login_message_fallback = '登录过期,请重新登录'

  1. refresh_viewrefresh_message 设置刷新页面的端点名称和刷新提示消息。用于处理会话刷新的逻辑。

login_manager.refresh_view = 'refresh'
login_manager.refresh_message = '会话已刷新'

  1. needs_refresh_message 设置需要刷新的消息。当用户在进行敏感操作时,如果会话即将过期,可以通过此配置项设置提示消息。

login_manager.needs_refresh_message = '请重新登录以继续'

  1. expired_messageexpired_message_category 设置会话过期的提示消息和消息的类别。

login_manager.expired_message = '会话已过期,请重新登录'
login_manager.expired_message_category = 'warning'

  1. session_protection 设置会话保护的级别,可以是 Nonebasicstrong 中的一个。默认为 None
  • None:不启用会话保护。
  • basic:启用基本的会话保护,检测 IP 地址和用户代理是否变化。
  • strong:启用强制的会话保护,检测 IP 地址、用户代理和用户 ID 是否变化。

login_manager.session_protection = 'strong'

这些配置项可以根据你的应用需求进行定制,确保在初始化 LoginManager 对象后进行配置。例如:

from flask import Flask
from flask_login import LoginManager

app = Flask(__name__)
login_manager = LoginManager(app)

# 设置登录页面的端点名称
login_manager.login_view = 'login'
# 设置登录提示消息
login_manager.login_message = '请先登录'
# 设置刷新页面的端点名称
login_manager.refresh_view = 'refresh'
# 设置会话保护级别为 'strong'
login_manager.session_protection = 'strong'

login_required装饰器

@login_required装饰器是 Flask-Login 扩展提供的一个装饰器,用于保护需要用户登录才能访问的视图函数。使用这个装饰器,可以地限制某些路由只能被已登录用户访问。

注意,在使用login_required装饰器的时候,要将其卸载路由装饰器后面.

从零开始构建报警中心:part09 使用flask-login实现用户登入登出_flask

登入登出路由

@app.route('/login', methods=["GET", "POST"])
def login():
    """
    :return:
    """
    username = request.args.get('username', None)
    if username:
        user = User(username)
        login_user(user)
        session['user_id'] = username
        return '当前用户为:%s' % username
    else:
        return '请先登录'


@app.route('/logout')
@login_required
def logout():
    """
    退出登录
    :return:
    """
    # --start-- 本地系统logout
    logout_user()
    session.pop('user_id', None)

    return redirect(url_for('index'))



完整代码

from flask import Flask, redirect, request, session, url_for
from db import db
from flask_login import LoginManager, login_user, UserMixin, current_user, login_required, logout_user


app = Flask(__name__, template_folder="templates")
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///test.db'  # 使用SQLite数据库,可以根据需要更改
app.config['SECRET_KEY'] = "x0jasj082-gam=asesfda89j"
# secret_key flask和扩展使用它来保证数据安全, 它被设置为'dev'开发期间提供一个方便的值,但在部署时应随机覆盖它
db.init_app(app)  # 初始化绑定DB 与 Flask
login_manager = LoginManager(app)  # Setup a Flask-Login Manager
login_manager.login_view = "login"  # required_login 校验不通过,默认跳转


class User(UserMixin):
    """
    flask-login 必要 User类
    """
    def __init__(self, username):
        self.username = username

    def __repr__(self):
        return self.username

    def get_id(self):
        return self.username


# 用户加载函数
@login_manager.user_loader
def load_user(user_id):
    return User(user_id)


# 定义错误处理函数,捕获404错误
@app.errorhandler(404)
def page_not_found(error):
    # 重定向到根路由
    return redirect(url_for('index'))


# 定义根路由
@app.route('/')
@login_required
def index():
    user = current_user
    return '欢迎你, ' + user.username


@app.route('/login', methods=["GET", "POST"])
def login():
    """
    :return:
    """
    username = request.args.get('username', None)
    if username:
        user = User(username)
        login_user(user)
        session['user_id'] = username
        return '当前用户为:%s' % username
    else:
        return '请先登录'


@app.route('/logout')
@login_required
def logout():
    """
    退出登录
    :return:
    """
    # --start-- 本地系统logout
    logout_user()
    session.pop('user_id', None)

    return redirect(url_for('index'))


if __name__ == '__main__':
    app.run(debug=True)

运行效果

未登录情况先访问/,跳转到login

从零开始构建报警中心:part09 使用flask-login实现用户登入登出_flask-login_02

未登录情况下,不携带args访问/login

从零开始构建报警中心:part09 使用flask-login实现用户登入登出_flask_03

携带args访问/login模拟登陆

从零开始构建报警中心:part09 使用flask-login实现用户登入登出_flask-login_04

登陆后访问/

从零开始构建报警中心:part09 使用flask-login实现用户登入登出_flask-login_05

举报

相关推荐

0 条评论