如何用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)
测试流程
- 运行代码后访问
http://127.0.0.1:5000/register注册账号 - 注册完成后跳转登录页,输入账号密码登录
- 登录成功后自动跳转到
dashboard页,即可看到当前用户的专属内容 - 点击登出后会清除会话,再次访问
dashboard会跳转登录页
生产环境优化建议
- 不要硬编码
SECRET_KEY,改为从系统环境变量读取 - 新增CSRF防护,可使用
flask-wtf扩展实现 - SQLite仅适合小型场景,用户量较大时建议替换为MySQL/PostgreSQL
- 新增参数校验逻辑,避免恶意输入导致的异常
- 可增加JWT令牌支持,适配前后端分离架构
内容的提问来源于stack exchange,提问作者Arnab Chatterjee
相关产品推荐
相关产品推荐

