编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

Flask-Login处理用户登录和认证(flask login current_user)

wxchong 2024-11-10 12:14:21 开源技术 141 ℃ 0 评论

Flask-Login 是一个用于处理用户登录和认证的 Flask 扩展。它帮助管理用户会话,实现登录、注销和对页面的访问控制。结合 Flask-SQLAlchemy,Flask-Login 可以帮助开发者快速实现用户认证功能。

1. 安装 Flask-Login

首先,确保安装了 Flask-Login:

pip install Flask-Login

2. 基本使用流程

  • 定义用户模型:创建一个包含认证相关字段的用户模型,并实现 Flask-Login 所需的几个方法。
  • 加载用户:通过用户 ID 从数据库中加载用户。
  • 管理登录会话:处理用户的登录、注销、访问控制等操作。

3. 配置 Flask-Login

项目结构

my_flask_app/
│
├── app.py                 # Flask 应用文件
└── templates/             # HTML 模板目录
    └── login.html         # 用户登录页面

代码示例

  1. 导入 Flask-Login 并配置应用
from flask import Flask, render_template, redirect, url_for, flash, request
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///mydatabase.db'
app.config['SECRET_KEY'] = 'your_secret_key'

db = SQLAlchemy(app)
login_manager = LoginManager(app)

# 当用户未登录时,重定向到登录页面
login_manager.login_view = 'login'
login_manager.login_message = 'Please log in to access this page.'

# 定义用户模型
class User(db.Model, UserMixin):  # 继承 UserMixin 提供 Flask-Login 所需的方法
    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)

    def __repr__(self):
        return f'<User {self.username}>'

# 创建数据库
@app.before_first_request
def create_tables():
    db.create_all()

# Flask-Login 所需的用户加载函数
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

# 登录视图
@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        # 查询数据库验证用户
        user = User.query.filter_by(username=username).first()
        if user and user.password == password:  # 简单的密码验证(建议加密密码)
            login_user(user)  # 登录用户
            flash('Logged in successfully!', 'success')
            return redirect(url_for('protected'))
        else:
            flash('Invalid username or password', 'danger')
    
    return render_template('login.html')

# 受保护的视图,要求登录
@app.route('/protected')
@login_required  # 使用 Flask-Login 的装饰器保护路由
def protected():
    return f'Hello, {current_user.username}! This is a protected page.'

# 注销视图
@app.route('/logout')
@login_required
def logout():
    logout_user()  # 注销用户
    flash('You have been logged out.', 'info')
    return redirect(url_for('login'))

if __name__ == '__main__':
    app.run(debug=True)
  1. HTML 模板 login.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
</head>
<body>
    <h1>Login</h1>
    <form method="POST">
        <p>
            <label for="username">Username:</label>
            <input type="text" name="username" id="username" required>
        </p>
        <p>
            <label for="password">Password:</label>
            <input type="password" name="password" id="password" required>
        </p>
        <p>
            <input type="submit" value="Login">
        </p>
    </form>

    <!-- 显示闪存消息 -->
    {% with messages = get_flashed_messages(with_categories=true) %}
        {% if messages %}
            <ul>
                {% for category, message in messages %}
                    <li><strong>{{ category }}</strong>: {{ message }}</li>
                {% endfor %}
            </ul>
        {% endif %}
    {% endwith %}
</body>
</html>

4. 代码解释

1. 用户模型 (User)

  • UserMixin:提供了 Flask-Login 所需的基本方法,如 is_authenticatedis_activeis_anonymousget_id(),用于表示用户的状态。
  • idusernamepassword:定义了用户表结构。id 是主键,username 是唯一的用户标识,password 存储用户的密码(应加密处理,示例中为简单的文本存储)。

2. LoginManager和用户加载函数

  • LoginManager:是 Flask-Login 的核心对象,管理用户的登录状态。
  • user_loader():该函数用于通过用户 ID 加载用户实例,Flask-Login 使用它来维护用户会话。

3. login_user()和 logout_user()

  • login_user(user):将用户标记为已登录,建立用户会话。
  • logout_user():注销当前登录用户,清除用户会话。

4. 受保护的视图

  • @login_required:这是 Flask-Login 提供的装饰器,作用是确保只有已登录的用户才能访问某些页面。未登录用户将被重定向到 login_view 所指定的登录页面。

5. current_user

  • current_user:Flask-Login 提供的全局对象,表示当前登录的用户。可以使用 current_user.username 获取登录用户的信息。

5. 密码加密和验证

为确保安全性,实际应用中不应直接存储明文密码,推荐使用密码哈希加密库,例如 werkzeug.security 提供的 generate_password_hashcheck_password_hash

from werkzeug.security import generate_password_hash, check_password_hash

# 在注册时加密密码
hashed_password = generate_password_hash(password)

# 在登录时验证密码
if user and check_password_hash(user.password, password):
    login_user(user)

修改后的 User 模型应将 password 存储为加密后的哈希值。

class User(db.Model, UserMixin):
    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)

    def set_password(self, password):
        self.password = generate_password_hash(password)

    def check_password(self, password):
        return check_password_hash(self.password, password)

6. 记住我功能

Flask-Login 还支持“记住我”功能,允许用户在关闭浏览器后保持登录状态。

login_user() 中,可以使用 remember=True 来启用此功能:

login_user(user, remember=True)

你还需要在登录表单中提供一个“记住我”选项。

7. 总结

Flask-Login 提供了一种简单且有效的方式来处理用户登录、认证和访问控制。结合 Flask-SQLAlchemy,你可以轻松管理用户会话并保护应用中的敏感页面。通过 @login_requiredcurrent_user,你可以控制用户的访问权限,并获取当前登录的用户信息。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表