Tkinter制作登录界面以及登陆后页面切换--用户数据从数据库获取并进行合法性校验(二)

Tkinter制作登录界面以及登陆后页面切换(二)

  • 新增功能
    • [1. 数据库管理(SqlLite)](#1. 数据库管理(SqlLite))
    • [2. 用户表创建(用户信息增删改查操作)](#2. 用户表创建(用户信息增删改查操作))
    • [3. 完善登录校验](#3. 完善登录校验)

续接上集,废话不多说,开搞!

新增功能

  1. 数据库管理
  2. 用户表创建(用户信息增删改查操作)
  3. 完善登录校验

1. 数据库管理(SqlLite)

下面代码中 from data import Sql, BcryptUtils 引入的是自己写的包,Sql用来记录需要初始化的信息(创建基础表,添加管理用户等), BcryptUtils 主要是对密码进行加密哈希和校验密码是否正确

python 复制代码
import json
import sqlite3

from data import Sql, BcryptUtils


class SqlUtils:
    def __init__(self):
        # 不再在初始化时直接建立连接,而是在需要时建立
        self.database_name = 'platform.db'

    def init(self):
        """ 初始化数据库 """
        # 创建基础数据表和初始化表单数据时建立连接并在完成后关闭
        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            for sql in Sql.create_sqls:
                cursor.execute(sql)
            for sql in Sql.insert_sqls:
                cursor.execute(sql)
            conn.commit()

    def query(self, sql):
        """
        查询数据,返回格式:{'字段名':'数值'}
        :param sql: 需要查询的sql
        :return: 返回查询到的数据,没有数据时返回None
        """
        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            cursor.execute(sql)
            _rows = cursor.fetchall()
            columns = [description[0] for description in cursor.description]
            return [dict(zip(columns, _row)) for _row in _rows]

    def insert(self, sql: str):
        """
        插入数据方法
        :param sql: 插入数据的sql
        :return: 成功返回True,否则False
        """
        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            cursor.execute(sql)
            conn.commit()
            rows_affected = cursor.rowcount
            return rows_affected > 0

    def insert_json(self, table_name: str, data_dict: json) -> object:
        # 解析 JSON 获取键值对
        columns = ', '.join(data_dict.keys())
        placeholders = ', '.join(['?'] * len(data_dict))
        values = tuple(data_dict.values())

        with sqlite3.connect(self.database_name) as conn:
            cursor = conn.cursor()
            # 拼接 SQL 语句
            sql = f"INSERT INTO {table_name} ({columns}) VALUES ({placeholders})"
            try:
                cursor.execute(sql, values)
                conn.commit()
                return True
            except Exception as e:
                print(f"插入失败:{e}")
                conn.rollback()
                return False

    def delete(self, table_name: str, data_dict: json):
        if not data_dict or len(data_dict) == 0:
            return False, "条件为空,不允许删除。"
        conditions = []
        values = []
        for key, value in data_dict.items():
            conditions.append(f"{key}=?")
            values.append(value)
        sql = f"DELETE FROM {table_name} WHERE {' AND '.join(conditions)}"
        with sqlite3.connect(self.database_name) as conn:
            try:
                cursor = conn.cursor()
                cursor.execute(sql, values)
                conn.commit()
                rows_affected = cursor.rowcount
                return rows_affected > 0
            except Exception as e:
                print(f"删除失败:{e}")
                conn.rollback()
                return False

    def login_user(self, username, password):
        """
        用户登录判断接口,返回True代表允许登录
        :param username: 用户账号
        :param password: 用户密码
        :return: 成功返回True,用户数据,失败则返回False,原因
        """
        user_data = self.query(f"SELECT * FROM sys_user WHERE username='{username}'")
        if user_data:
            row = user_data[0]
            if BcryptUtils.check_password(password, row['password']):
                return True, row
            else:
                return False, '账号或密码错误'
        else:
            return False, "没有当前登录的账号信息。"


if __name__ == '__main__':
    sql_utils = SqlUtils()
    sql_utils.init()
    sql_utils.insert_json("sys_user", {
        "name": "测试", "username": "admin",
        "password": BcryptUtils.hash_password('123456')
    })
    input_username = "admin"
    input_password = "123456"
    res, data = sql_utils.login_user(input_username, input_password)
    if res is True:
        extend_str = data.get('extend')
        extend_dict = json.loads(extend_str) if extend_str else {}
        print(f"欢迎您,{data.get('name')},您的账号是:{data.get('username')},头像:{extend_dict.get('img')}")
    else:
        print(f'{data}')
    # 删除用户
    sql_utils.delete("sys_user", {
        "username": "admin"
    })

2. 用户表创建(用户信息增删改查操作)

data/Sql.py

python 复制代码
create_sqls = []

create_drop_user = "DROP TABLE IF EXISTS sys_user;"
create_sqls.append(create_drop_user)

create_user = '''
        CREATE TABLE IF NOT EXISTS sys_user
        (
            id        INTEGER PRIMARY KEY,
            name      varchar(255)       not null,
            username  varchar(32)        not null,
            password  varchar(255)       not null,
            is_active blob default false not null,
            extend    json,
            unique (username)
        );
        '''
create_sqls.append(create_user)

insert_sqls = []

insert_user = """
insert into sys_user(name, username, password, extend)
        values ('超级管理员', 'admin', 
        '$2b$12$v/PNEi9kMoAafg17SneZ8eiX2/CC/BGWjCI4l.ynkfLcRhXm4TPdW', 
        '{"img":"http:127.0.0.1/statics/super/image/super.png"}');
"""
insert_sqls.append(insert_user)

3. 完善登录校验

data/BcryptUtils.py ,引入依赖命令: pip install bcrypt

python 复制代码
import bcrypt


def check_password(plain_password, hashed_password):
    """
    验证密码
    :param plain_password: 明文密码
    :param hashed_password: 哈希密码
    :return: 匹配则返回True,否则返回False
    """
    plain_password = plain_password.encode('utf-8')
    hashed_password = hashed_password.encode('utf-8')
    return bcrypt.checkpw(plain_password, hashed_password)


def hash_password(password):
    """
    对密码进行加密
    :param password: 用户密码
    :return: 返回加密的密文
    """
    password = password.encode('utf-8')
    hashed = bcrypt.hashpw(password, bcrypt.gensalt())
    return hashed.decode('utf-8')

login/ui.py 不清楚这个去看一下一中的ui.py全代码,此处只展示修改的信息

python 复制代码
from data.SqlLiteUtils import SqlUtils


class Controller:
    # 导入UI类后,替换以下的 object 类型,将获得 IDE 属性提示功能
    ui: WinGUI

    def __init__(self):
        ....保持原有代码....下方是新增代码
        self.sql_utils = SqlUtils()
    
    def login_submit(self, evt):
        u, p = self.ui.login()
        if u is None or len(u) == 0:
            tkinter.messagebox.showinfo("登录提示", "请输入登录用户名!")
        elif p is None or len(p) == 0:
            tkinter.messagebox.showinfo("登录提示", "请输入登录密码!")
        print(
            f"触发了登录操作,地址:{self.url},账号:{u},密码:{p}")
        res, user = self.sql_utils.login_user(u, p)
        if res is True:
            print(f"欢迎您,{user.get('name')}")
            self.ui.destroy()
            from home.control import Controller as HomeUIController
            from home.ui import Win as MainWin
            app = MainWin(HomeUIController())
            app.set_user(user)
            app.mainloop()
        else:
            tkinter.messagebox.showinfo("登录提示", user)

home/ui.py 此处一样只展示心增代码

python 复制代码
class WinGUI(Tk):
    def __init__(self):
        super().__init__()
		self.user: json = {}
		
	def set_user(self, user: json):
        self.user = user

好了,到这里结束了,后续会开始做注册用户操作,需要整体源代码的可以留言或SL俺!

相关推荐
Scott9999HH6 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
AI云海7 小时前
python 列表、元组、集合和字典
开发语言·python
二十雨辰8 小时前
[爬虫]-Urllib
爬虫·python
玉鸯10 小时前
Agent Hook:在概率推理之上,为 Agent 叠加确定性控制
python·langchain·agent
weixin_4462608510 小时前
HACO:面向动态部署环境的对冲式智能计算可靠多智能体调度框架
后端·python·flask
我的xiaodoujiao10 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
qetfw11 小时前
MXU:Tauri 2 + React 的 MaaFramework 跨平台 GUI 源码
前端·python·react.js·前端框架·开源项目·效率工具
用户83562907805112 小时前
Python 实现 Excel 页面布局与打印设置自动化
后端·python
一次旅行12 小时前
Python+大模型端到端自动化日报系统
开发语言·python·自动化