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

MySQL集成校园管理系统登录验证cur.fetchall()匹配异常问题

登录验证函数的MySQL查询问题及解决办法

问题背景

我正在为校园项目开发一套管理系统,需集成MySQL数据库。定义了verify_login()函数,用于根据用户角色(管理员/访客)展示对应界面。MySQL登录表包含role和password两列,分别存储'admin'和'guest'对应的数据。

现有代码

import mysql.connector as connector

conn = connector.connect(host='localhost', username='root', password='root', database='ip_project')
cur = conn.cursor()

def verify_login(win: Tk, role, pwd):
    cred = [(role.strip().lower(), pwd)]
    
    cur.execute(f'SELECT * FROM LOGIN WHERE ROLE = "{role.lower()}"')
    
    if cred == cur.fetchall() and role == 'admin'.casefold():
        win.destroy()
        
        admin()
    elif cred == cur.fetchall() and role == 'guest'.casefold():
        win.destroy()
        
        guest()
    elif cred != cur.fetchall():
        mb.showerror('Login failed!', 'The entered username and password are incorrect! \nPlease recheck them and try again')

问题现象

  • 当cred为[('guest', 'guest')]时,总是弹出错误提示框;
  • 当cred为[('admin', 'admin')]时,仅约60%概率能正常进入管理员界面;
  • 访客登录失败后再尝试管理员登录也无法成功。

解决方案

1. 核心问题:游标结果被重复读取耗尽

cur.fetchall()会一次性取出游标中的所有结果,之后游标就会处于空状态。你连续三次调用cur.fetchall():

  • 第一次if判断时已取空结果;
  • 后续elif判断时,cur.fetchall()返回空列表[],自然和cred不相等,导致逻辑错误。

修复: 先将查询结果存入变量,再用该变量完成所有判断:

def verify_login(win: Tk, role, pwd):
    role_lower = role.strip().lower()
    cred = [(role_lower, pwd)]
    
    cur.execute(f'SELECT * FROM LOGIN WHERE ROLE = "{role_lower}"')
    # 先存储查询结果,避免重复读取游标
    db_result = cur.fetchall()
    
    if cred == db_result:
        win.destroy()
        if role_lower == 'admin':
            admin()
        elif role_lower == 'guest':
            guest()
    else:
        mb.showerror('Login failed!', 'The entered username and password are incorrect! \nPlease recheck them and try again')

2. 修复SQL注入漏洞

原代码用字符串拼接生成SQL语句,存在SQL注入风险,改用参数化查询:

# 替换原execute语句
cur.execute('SELECT * FROM LOGIN WHERE ROLE = %s', (role_lower,))

3. 优化数据库连接管理

全局连接和游标容易因长期占用导致异常,建议在函数内创建并及时关闭:

def verify_login(win: Tk, role, pwd):
    role_lower = role.strip().lower()
    cred = [(role_lower, pwd)]
    
    # 函数内创建连接和游标,使用后关闭
    conn = connector.connect(host='localhost', username='root', password='root', database='ip_project')
    cur = conn.cursor()
    
    try:
        cur.execute('SELECT * FROM LOGIN WHERE ROLE = %s', (role_lower,))
        db_result = cur.fetchall()
        
        if cred == db_result:
            win.destroy()
            if role_lower == 'admin':
                admin()
            elif role_lower == 'guest':
                guest()
        else:
            mb.showerror('Login failed!', 'The entered username and password are incorrect! \nPlease recheck them and try again')
    finally:
        # 确保资源被释放
        cur.close()
        conn.close()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 17:40:46