【Flask实战】Flask知识点总结(三)— Flask-Login使用

导读:本篇文章讲解 【Flask实战】Flask知识点总结(三)— Flask-Login使用,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

📃内容主要来自《Flask Web开发实战:入门、进阶与原理解析》作者:李辉
😏面向群体:

  • flask初学者可用来复习知识点
  • 已经有flask开发经验可用来收藏备查

📱有问题随时与我联系,一起学习交流
❤️喜欢的话点个三连吧

上一篇:【Flask实战】Flask知识点总结(二)

Flask-Login安装

pip install flask-login

初始化

除了实例化扩展类之外,我们还要实现一个“用户加载回调函数”,具体代码如下所示:

from flask_login import LoginManager

login_manager = LoginManager(app)  # 实例化扩展类

@login_manager.user_loader
def load_user(user_id):  # 创建用户加载回调函数,接受用户 ID 作为参数
    user = User.query.get(int(user_id))  # 用 ID 作为 User 模型的主键查询对应的用户
    return user  # 返回用户对象

Flask-Login 提供了一个 current_user 变量,注册这个函数的目的是,当程序运行后,如果用户已登录, current_user 变量的值会是当前用户的用户模型类记录。
另一个步骤是让存储用户的 User 模型类继承 Flask-Login 提供的 UserMixin 类:

from flask_login import UserMixin

class User(db.Model, UserMixin):
    # ...

继承这个类会让 User 类拥有几个用于判断认证状态的属性和方法,其中最常用的是 is_authenticated 属性:如果当前用户已经登录,那么 current_user.is_authenticated 会返回 True, 否则返回 False。有了 current_user 变量和这几个验证方法和属性,我们可以很轻松的判断当前用户的认证状态。

登录示例

登录用户使用 Flask-Login 提供的 login_user() 函数实现,需要传入用户模型类对象作为参数。下面是用于显示登录页面和处理登录表单提交请求的视图函数:

from flask_login import login_user

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        if not username or not password:
            flash('Invalid input.')
            return redirect(url_for('login'))

        user = User.query.first()
        # 验证用户名和密码是否一致
        if username == user.username and user.validate_password(password):
            login_user(user)  # 登入用户
            flash('Login success.')
            return redirect(url_for('index'))  # 重定向到主页

        flash('Invalid username or password.')  # 如果验证失败,显示错误消息
        return redirect(url_for('login'))  # 重定向回登录页面

    return render_template('login.html')

登出示例

和登录相对,登出操作则需要调用 logout_user() 函数,使用下面的视图函数实现:

from flask_login import login_required, logout_user

@app.route('/logout')
@login_required  # 用于视图保护
def logout():
    logout_user()  # 登出用户
    flash('Goodbye.')
    return redirect(url_for('index'))  # 重定向回首页

认证保护

在 Web 程序中,有些页面或 URL 不允许未登录的用户访问,而页面上有些内容则需要对未登陆的用户隐藏,这就是认证保护。包括:

  • 视图保护
  • 模板内容保护

视图保护

在视图保护层面来说,未登录用户不能执行下面的操作:

  • 不能对数据进行增加、删除、修改操作。

对于不允许未登录用户访问的视图,只需要为视图函数附加一个 login_required 装饰器就可以将未登录用户拒之门外。以删除条目视图为例:

@app.route('/movie/delete/<int:movie_id>', methods=['POST'])
@login_required  # 登录保护
def delete(movie_id):
    movie = Movie.query.get_or_404(movie_id)
    db.session.delete(movie)
    db.session.commit()
    flash('Item deleted.')
    return redirect(url_for('index'))

添加了这个装饰器后,如果未登录的用户访问对应的 URL,Flask-Login 会把用户重定向到登录页面,并显示一个错误提示。为了让这个重定向操作正确执行,我们还需要把 login_manager.login_view 的值设为我们程序的登录视图端点(函数名),把下面这一行代码放到 login_manager 实例定义下面即可:

login_manager.login_view = 'login'

需要的话,可以通过设置 login_manager.login_message 来自定义错误提示消息。
创建新条目的操作稍微有些不同,因为对应的视图同时处理显示页面的 GET 请求和创建新条目的 POST 请求,我们仅需要禁止未登录用户创建新条目,因此不能使用 login_required,而是在函数内部的 POST 请求处理代码前进行过滤:

from flask_login import login_required, current_user

# ...

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        if not current_user.is_authenticated:  # 如果当前用户未认证
            return redirect(url_for('index'))  # 重定向到主页
        # ...

模板内容保护

认证保护的另一形式是页面模板内容的保护。比如,不能对未登录用户显示下列内容:

  • 增加、删除、修改的元素
    这几个元素的定义都在首页模板(index.html)中,以创建新条目表单为例,我们在表单外部添加一个 if 判断:
<!-- 在模板中可以直接使用 current_user 变量 -->
{% if current_user.is_authenticated %}
<form method="post">
    Name <input type="text" name="title" autocomplete="off" required>
    Year <input type="text" name="year" autocomplete="off" required>
    <input class="btn" type="submit" name="submit" value="Add">
</form>
{% endif %}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/63047.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!