当前位置: 首页 > article >正文

Flask-Login完整使用案例

下面是一个完整的 Flask-Login 使用案例,涵盖以下功能:

  • 用户注册
  • 用户登录
  • 访问受保护页面
  • 退出登录

1. 安装依赖

pip install flask flask-login flask-wtf flask-sqlalchemy werkzeug

2. 创建 Flask 项目结构

flask_login_demo/
│── app.py           # Flask 入口文件
│── models.py        # 数据库模型
│── forms.py         # 表单
│── config.py        # 配置文件
│── templates/
│   │── base.html    # 基础模板
│   │── login.html   # 登录页面
│   │── register.html# 注册页面
│   └── home.html    # 主页
└── database.db      # SQLite 数据库文件(运行后自动生成)

3. 配置 Flask 应用 (config.py)

import os

class Config:
    SECRET_KEY = 'your_secret_key'  # 用于 CSRF 保护
    SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db'  # 数据库
    SQLALCHEMY_TRACK_MODIFICATIONS = False

4. 创建数据库模型 (models.py)

from flask_sqlalchemy import SQLAlchemy
from flask_login import UserMixin

db = SQLAlchemy()

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(200), nullable=False)

5. 定义表单 (forms.py)

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, EqualTo

class RegisterForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired(), Length(min=4, max=20)])
    password = PasswordField('密码', validators=[DataRequired(), Length(min=6, max=20)])
    confirm_password = PasswordField('确认密码', validators=[DataRequired(), EqualTo('password')])
    submit = SubmitField('注册')

class LoginForm(FlaskForm):
    username = StringField('用户名', validators=[DataRequired()])
    password = PasswordField('密码', validators=[DataRequired()])
    submit = SubmitField('登录')

6. 编写 Flask 逻辑 (app.py)

from flask import Flask, render_template, redirect, url_for, flash
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, UserMixin, login_user, logout_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
from models import db, User
from forms import RegisterForm, LoginForm
from config import Config

app = Flask(__name__)
app.config.from_object(Config)

# 初始化数据库
db.init_app(app)

# 初始化 Flask-Login
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'  # 如果未登录,则重定向到 login 视图

# 加载用户
@login_manager.user_loader
def load_user(user_id):
    return User.query.get(int(user_id))

@app.route('/')
def home():
    return render_template('home.html')

@app.route('/register', methods=['GET', 'POST'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        # 检查用户名是否存在
        existing_user = User.query.filter_by(username=form.username.data).first()
        if existing_user:
            flash('用户名已存在', 'danger')
            return redirect(url_for('register'))

        # 创建新用户
        hashed_password = generate_password_hash(form.password.data)
        new_user = User(username=form.username.data, password=hashed_password)
        db.session.add(new_user)
        db.session.commit()
        flash('注册成功,请登录', 'success')
        return redirect(url_for('login'))

    return render_template('register.html', form=form)

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and check_password_hash(user.password, form.password.data):
            login_user(user)  # 登录用户
            flash('登录成功!', 'success')
            return redirect(url_for('dashboard'))
        else:
            flash('用户名或密码错误', 'danger')

    return render_template('login.html', form=form)

@app.route('/dashboard')
@login_required
def dashboard():
    return f"欢迎 {current_user.username} 进入后台! <a href='{url_for('logout')}'>登出</a>"

@app.route('/logout')
@login_required
def logout():
    logout_user()
    flash('已成功登出', 'info')
    return redirect(url_for('login'))

# 初始化数据库
with app.app_context():
    db.create_all()

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

7. 创建 HTML 模板 (templates/ 目录)

base.html
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}Flask-Login 示例{% endblock %}</title>
</head>
<body>
    {% with messages = get_flashed_messages(with_categories=true) %}
        {% if messages %}
            {% for category, message in messages %}
                <p style="color: {{ 'red' if category == 'danger' else 'green' }}">{{ message }}</p>
            {% endfor %}
        {% endif %}
    {% endwith %}
    {% block content %}{% endblock %}
</body>
</html>

home.html
{% extends 'base.html' %}
{% block title %}主页{% endblock %}
{% block content %}
    <h1>欢迎来到 Flask-Login 示例</h1>
    <a href="{{ url_for('login') }}">登录</a> | 
    <a href="{{ url_for('register') }}">注册</a>
{% endblock %}

register.html
{% extends 'base.html' %}
{% block title %}注册{% endblock %}
{% block content %}
    <h1>注册</h1>
    <form method="POST">
        {{ form.hidden_tag() }}
        <p>{{ form.username.label }} {{ form.username }}</p>
        <p>{{ form.password.label }} {{ form.password }}</p>
        <p>{{ form.confirm_password.label }} {{ form.confirm_password }}</p>
        <p>{{ form.submit }}</p>
    </form>
{% endblock %}

login.html
{% extends 'base.html' %}
{% block title %}登录{% endblock %}
{% block content %}
    <h1>登录</h1>
    <form method="POST">
        {{ form.hidden_tag() }}
        <p>{{ form.username.label }} {{ form.username }}</p>
        <p>{{ form.password.label }} {{ form.password }}</p>
        <p>{{ form.submit }}</p>
    </form>
{% endblock %}

8. 运行应用

python app.py

然后访问:

  • 主页
  • 注册
  • 登录

9. 关键点解析

  • Flask-Login 通过 login_user(user) 实现登录。
  • @login_required 保护 dashboard 视图,未登录用户会被重定向到 login
  • current_user 获取当前登录的用户。
  • logout_user() 退出登录。

这个示例是一个完整的 Flask-Login 用户认证流程,可以用于实际项目! 🚀


http://www.kler.cn/a/586104.html

相关文章:

  • iOS 模块化架构设计:主流方案与实现详解
  • SpringCloud 学习笔记1(Spring概述、工程搭建、注册中心、负载均衡、 SpringCloud LoadBalancer)
  • 大数据如何赋能零售行业进行产品创新
  • 大语言模型微调和大语言模型应用的区别?
  • 基于SpringBoot + Vue 的房屋租赁系统
  • Spring Boot 读取 ZooKeeper (ZK) 属性的总结指南
  • 基于javaweb的SpringBoot杂物商城系统设计与实现(源码+文档+部署讲解)
  • ES6 字符串和正则表达式
  • 基于群智能算法的三维无线传感网络覆盖优化数学模型-可以使用群智能算法直接调用进行优化,完整MATLAB代码
  • 解析Doris编译脚本env.sh的逻辑
  • Maven安装、idea集成Maven、Maven依赖管理、Maven生命周期
  • C语言中的流程控制语句
  • Linux》》Ubuntu apt 常用命令汇总,Linux 文件目录结构 修改root 密码 查看系统版本
  • G-Star 公益行 | 温暖相约 3.30 上海「开源×AI 赋能公益」Meetup
  • 图论入门【数据结构基础】:什么是图?如何表示图?
  • SpringBoot第二天
  • 深搜专题9:取数游戏
  • C++11多线程,锁与条件变量
  • 【CXX】6.7 SharedPtr<T> — std::shared_ptr<T>
  • 网络_面试_HTTP请求报文和HTTP响应报文