
本文讲解如何正确使用参数化查询从 mysql 表中检索同时匹配用户名和密码的单行记录,重点纠正 sql 语法错误、防止 sql 注入,并提供可直接运行的安全示例代码。
在实现登录功能时,一个常见误区是试图用 WHERE col1, col2 LIKE '%s','%s' 这类语法同时匹配多个字段——这在 SQL 中完全无效。MySQL 不支持这种元组式比较;正确的做法是对每个字段单独判断,并用逻辑运算符 AND 连接。
此外,原始代码中使用 % 字符串格式化拼接 SQL(如 "..."%(username,password))存在严重安全隐患:一旦用户输入恶意内容(例如 ' OR '1'='1),将导致 SQL 注入攻击,可能泄露全部用户数据甚至破坏数据库。
✅ 正确写法应采用参数化查询(即预编译语句 + 占位符),由数据库驱动(如 mysql-connector-python 或 PyMySQL)自动转义参数:
# ✅ 安全、标准的写法
cursor.execute("SELECT * FROM user WHERE username = %s AND password = %s", (username, password))
ecreds = cursor.fetchall()
if len(ecreds) == 1:
print("Login successful. Welcome, " + ecreds[0][1]) # 假设 name 在第二列⚠️ 注意事项:
立即学习“Python免费学习笔记(深入)”;
- 使用 %s 占位符(MySQL 驱动专用)或 ?(SQLite)等,不要加引号,参数元组 (username, password) 由驱动自动处理;
- 永远避免 f-string 或 % 格式化拼接 SQL 字符串;
- 生产环境中,密码绝不能明文存储——务必使用 bcrypt、passlib 等库进行哈希(如 bcrypt.hashpw())并比对哈希值,而非直接比对明文密码;
- 若只需验证是否存在匹配,可用 cursor.fetchone() 替代 fetchall() 提升效率;
- 建议为 username 字段添加唯一索引,提升查询性能与数据一致性。
总结:一次安全的登录校验 = 正确的 SQL 条件(WHERE a = %s AND b = %s)+ 参数化执行 + 密码哈希存储。三者缺一不可。










