You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Flask和sqlite3实现支持多用户注册、分发用户专属存储内容的认证系统

实现思路总览

你需要拆分4个核心模块完成需求:

  • 基础依赖与Flask运行环境配置:依赖仅需要Flask和Werkzeug(Flask自带,用于密码哈希),sqlite3是Python标准库无需额外安装
  • SQLite数据库结构设计:需要2张核心表,分别存储用户身份信息、用户专属内容
  • 认证逻辑实现:包含用户注册、登录态校验、登出功能,用Flask原生session托管登录状态
  • 专属内容查询逻辑:登录后从会话中取用户ID,匹配数据库中对应用户的内容返回
分步实现代码

1. 依赖安装

执行命令安装所需依赖:

pip install flask

Werkzeug是Flask的内置依赖,无需单独安装,自带的密码哈希工具可避免明文存储用户密码。

2. 数据库初始化

首先创建数据库表结构,我们需要两张表:

  • users表:存储用户ID、用户名、加密后的密码
  • user_content表:存储用户ID对应的专属内容

初始化代码如下:

import sqlite3
from flask import Flask, request, session, redirect, url_for, render_template_string
from werkzeug.security import generate_password_hash, check_password_hash

app = Flask(__name__)
# 生产环境请将SECRET_KEY存入环境变量,不要硬编码在代码中
app.secret_key = 'your_secure_secret_key_here_replace_in_production'

def init_db():
    conn = sqlite3.connect('auth.db')
    c = conn.cursor()
    # 创建用户表
    c.execute('''
        CREATE TABLE IF NOT EXISTS users (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            username TEXT UNIQUE NOT NULL,
            password_hash TEXT NOT NULL
        )
    ''')
    # 创建用户专属内容表
    c.execute('''
        CREATE TABLE IF NOT EXISTS user_content (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            user_id INTEGER NOT NULL,
            content TEXT NOT NULL,
            FOREIGN KEY (user_id) REFERENCES users (id)
        )
    ''')
    conn.commit()
    conn.close()

# 启动时初始化数据库
init_db()

3. 用户注册接口实现

注册逻辑校验规则:用户名不能重复、密码不能为空,密码存入数据库前必须做哈希处理:

# 简易注册表单模板,实际项目可替换为独立HTML文件
REGISTER_FORM = '''
<form method="post">
    用户名:<input type="text" name="username" required><br>
    密码:<input type="password" name="password" required><br>
    <button type="submit">注册</button>
</form>
'''

@app.route('/register', methods=['GET', 'POST'])
def register():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        # 密码哈希处理
        password_hash = generate_password_hash(password)
        
        conn = sqlite3.connect('auth.db')
        c = conn.cursor()
        try:
            # 插入用户数据
            c.execute('INSERT INTO users (username, password_hash) VALUES (?, ?)', (username, password_hash))
            user_id = c.lastrowid
            # 给新用户插入默认专属内容,可根据需求修改
            c.execute('INSERT INTO user_content (user_id, content) VALUES (?, ?)', (user_id, f'欢迎你,{username}!这是你的专属内容'))
            conn.commit()
        except sqlite3.IntegrityError:
            conn.close()
            return '用户名已存在,请更换用户名重试'
        conn.close()
        return redirect(url_for('login'))
    return REGISTER_FORM

4. 登录与会话管理实现

登录成功后将用户ID存入session,后续所有请求均可通过session判断用户登录状态:

LOGIN_FORM = '''
<form method="post">
    用户名:<input type="text" name="username" required><br>
    密码:<input type="password" name="password" required><br>
    <button type="submit">登录</button>
</form>
'''

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']
        
        conn = sqlite3.connect('auth.db')
        c = conn.cursor()
        c.execute('SELECT id, password_hash FROM users WHERE username = ?', (username,))
        user = c.fetchone()
        conn.close()
        
        if user and check_password_hash(user[1], password):
            # 登录成功,将用户ID存入会话
            session['user_id'] = user[0]
            return redirect(url_for('dashboard'))
        return '用户名或密码错误'
    return LOGIN_FORM

@app.route('/logout')
def logout():
    # 清除会话中的用户ID,完成登出
    session.pop('user_id', None)
    return redirect(url_for('login'))

5. 专属内容查询接口实现

先校验登录状态,再根据会话中的用户ID查询对应专属内容:

@app.route('/dashboard')
def dashboard():
    # 校验用户是否登录
    user_id = session.get('user_id')
    if not user_id:
        return redirect(url_for('login'))
    
    conn = sqlite3.connect('auth.db')
    c = conn.cursor()
    c.execute('SELECT content FROM user_content WHERE user_id = ?', (user_id,))
    content = c.fetchone()[0]
    conn.close()
    
    return f'你的专属内容:{content}<br><a href="/logout">登出</a>'

if __name__ == '__main__':
    # 生产环境不要开启debug模式
    app.run(debug=True)
测试流程
  1. 运行代码后访问http://127.0.0.1:5000/register注册账号
  2. 注册完成后跳转登录页,输入账号密码登录
  3. 登录成功后自动跳转到dashboard页,即可看到当前用户的专属内容
  4. 点击登出后会清除会话,再次访问dashboard会跳转登录页
生产环境优化建议
  • 不要硬编码SECRET_KEY,改为从系统环境变量读取
  • 新增CSRF防护,可使用flask-wtf扩展实现
  • SQLite仅适合小型场景,用户量较大时建议替换为MySQL/PostgreSQL
  • 新增参数校验逻辑,避免恶意输入导致的异常
  • 可增加JWT令牌支持,适配前后端分离架构

内容的提问来源于stack exchange,提问作者Arnab Chatterjee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 07:27:04