Flask入门 — Flask_Login

Flask-Login 是一个为 Flask 应用程序设计的扩展,它简化了用户会话管理和认证过程。下面是一个详细的笔记格式讲解,帮助你学习如何使用 Flask-Login。

准备工作

安装 Flask-Login:

在你的 Flask 项目中,首先需要通过 pip 安装 Flask-Login 扩展。

pip install Flask-Login

引入 Flask-Login:

在你的主应用文件(如 app.py)顶部,引入 Flask-Login 模块。

from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user

初始化 LoginManager

在 Flask 应用实例化后,创建并初始化 LoginManager 对象。

ext.py

from flask_login import LoginManager
login_manager = LoginManager()
def LoginManagerConfig(app):
    login_manager.init_app(app)
    login_manager.login_view = 'main_bp.login'
    login_manager.login_message = '请先登录'

__init__.py

def create_app():
    app = Flask(__name__)
    app.config.from_object(Config)  # 配置文件
    # 注册蓝图
    app.register_blueprint(blueprint=routes)
    SQLAlchemyConfig(app)  # 数据库配置
    LoginManagerConfig(app)
    return app

用户模型(UserMixin)

为了与 Flask-Login 集成,你的用户模型需要继承 UserMixin 类,这提供了默认的实现,如 is_authenticatedis_activeis_anonymous, 和 get_id 方法。

class User(UserMixin, db.Model):  # 假设使用 SQLAlchemy 作为 ORM
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True)
    password_hash = db.Column(db.String(128))

    def check_password(self, password):
        # 实现密码校验逻辑
        pass

用户加载回调

告诉 Flask-Login 如何从数据库加载用户。

@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

登录与登出功能

登录

在处理登录请求的视图函数中,使用 login_user() 函数登录用户。

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    user = User.query.filter_by(username=username).first()
    if user and user.check_password(password):
        login_user(user)  # 登录成功
        return redirect(url_for('dashboard'))  # 重定向到仪表盘或其他页面
    else:
        return '用户名或密码错误'

登出

提供一个视图函数让用户登出。

@app.route('/logout')
@login_required  # 确保只有登录用户才能访问登出页面
def logout():
    logout_user()  # 登出用户
    return redirect(url_for('index'))  # 重定向到首页或其他页面

登录状态检查

使用 @login_required 装饰器可以保护视图,确保用户已登录。

@app.route('/dashboard')
@login_required
def dashboard():
    return '欢迎来到仪表盘,{}'.format(current_user.username)

当前登录用户

current_user 变量可以随时用来访问当前登录的用户信息。

@app.route('/profile')
@login_required
def profile():
    return '你好,{}!这是你的个人资料页面。'.format(current_user.username)

实例

当然,以下是一个简单的 Flask 应用案例,包括用户注册、登录和登出功能。这个案例假设你已经设置好了 Flask 环境,并且使用 SQLAlchemy 作为 ORM 连接到数据库。

创建模型model

# models.py : 数据库模型
from flask_login import UserMixin
from .ext import db


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)

迁移文件

flask db init
flask db migrate 
flask db upgrade 

路由视图函数文件views.py

# 使用 @login_manager.user_loader 装饰器定义用户加载回调函数
# 这个函数根据用户ID从数据库中加载用户对象,用于 Flask-Login 管理会话
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# 主页路由,渲染主页模板
@routes.route('/')
def index():
    return render_template('index.html')

# 注册路由,支持GET和POST方法
@routes.route('/register', methods=['GET''POST'])
def register():
    if request.method == 'POST':
        username = request.form.get('username')  # 获取表单提交的用户名
        password = request.form.get('password')  # 获取表单提交的密码
        hashed_password = generate_password_hash(password)  # 对密码进行哈希处理

        # 查询数据库中是否有相同的用户名,如果有则提示用户
        if User.query.filter_by(username=username).first():
            flash('该用户名已被注册,请选择其他用户名。')
            return redirect(url_for('main_bp.register'))  # 重定向回注册页面

        # 创建新用户对象并添加到数据库,然后提交
        new_user = User(username=username, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()
        
        # 注册成功后重定向到登录页面
        return redirect(url_for('main_bp.login'))
    
    # GET请求时,渲染注册页面模板
    return render_template('register.html')

# 登录路由,支持GET和POST方法
@routes.route('/login', methods=['GET''POST'])
def login():
    if request.method == 'POST':
        username = request.form.get('username')
        password = request.form.get('password')
        user = User.query.filter_by(username=username).first()

        # 验证用户名和密码是否匹配
        if user and check_password_hash(user.password, password):
            login_user(user)  # 登录用户
            return redirect(url_for('main_bp.dashboard'))  # 登录成功后跳转到仪表盘页面
        else:
            flash('登录失败,请检查用户名和密码。')  # 错误提示
    
    # GET请求或登录失败时,渲染登录页面模板
    return render_template('login.html')

# 仪表盘路由,需要登录才能访问
@routes.route('/dashboard')
@login_required
def dashboard():
    return render_template('dashboard.html', name=current_user.username)  # 传递当前用户姓名到模板

# 登出路由,需要登录才能访问
@routes.route('/logout')
@login_required
def logout():
    logout_user()  # 注销用户
    return redirect(url_for('main_bp.index'))  # 注销后重定向到首页

Jinja2模板文件

  • • index.html

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>首页</title></head><body>    <h1>Welcome to Flask App</h1>    <p><a href="{{ url_for('main_bp.login') }}">登录</a> 或者 <a href="{{ url_for('main_bp.register') }}">注册</a></p></body></html>
  • • register.html

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>注册</title></head><body>    {% with messages = get_flashed_messages() %}        {% if messages %}            <ul>            {% for message in messages %}                <li>{{ message }}</li>            {% endfor %}            </ul>        {% endif %}    {% endwith %}    <form method="POST" action="{{ url_for('main_bp.register') }}">        <label for="username">用户名:</label>        <input type="text" id="username" name="username" required>        <br>        <label for="password">密码:</label>        <input type="password" id="password" name="password" required>        <br>        <button type="submit">注册</button>    </form>    <p>已有账号? <a href="{{ url_for('main_bp.login') }}">登录</a></p></body></html>
  • • login.html

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>登录</title></head><body>    {% with messages = get_flashed_messages() %}        {% if messages %}            <ul>            {% for message in messages %}                <li>{{ message }}</li>            {% endfor %}            </ul>        {% endif %}    {% endwith %}    <form method="POST" action="{{ url_for('main_bp.login') }}">        <label for="username">用户名:</label>        <input type="text" id="username" name="username" required>        <br>        <label for="password">密码:</label>        <input type="password" id="password" name="password" required>        <br>        <button type="submit">登录</button>    </form>    <p>没有账号? <a href="{{ url_for('main_bp.register') }}">注册</a></p></body></html>
  • • dashboard.html

    <!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>仪表盘</title></head><body>    <h1>欢迎, {{ name }}!</h1>    <p>这是你的个人仪表盘。</p>    <a href="{{ url_for('main_bp.logout') }}">登出</a></body></html>

资料与代码

git clone https://gitee.com/ezemeti/FlaskLearn.git


原文始发于微信公众号(索隆程序员):Flask入门 — Flask_Login

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

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

(0)
服务端技术精选的头像服务端技术精选

相关推荐

发表回复

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