Python调用MariaDB存储过程验证用户登录失败问题排查
问题分析
你的核心问题是误解了cursor.callproc()的返回值:在Python的MySQL连接器中,callproc()返回的是传入的参数列表(用于处理OUT/INOUT参数的修改),而不是存储过程中SELECT语句的查询结果。所以你拿到的valido其实是(_email, _pass)组成的元组,判断valido==1永远不成立,直接返回valido就会显示邮箱值。
另外原代码还有两个小问题:
mysql.connection.commit()和cursor.close()写在return语句之后,永远不会执行,需要调整顺序- 登录验证属于查询操作,不需要执行
commit
解决方案
下面提供两种可行的解决方式:
方式1:修改存储过程,使用OUT参数返回验证结果
将存储过程改为通过OUT参数返回1/0,而非直接SELECT:
CREATE PROCEDURE iniciosesion( IN app_email varchar(50), IN app_pass varchar(50), OUT is_valid INT ) BEGIN IF EXISTS(SELECT 1 FROM Usuario WHERE Email = app_email AND Password = app_pass) THEN SET is_valid = 1; ELSE SET is_valid = 0; END IF; END$$
对应的Flask代码:
@app.route('/iniciarsesion', methods=['POST']) def sessiousuario(): cursor = mysql.connection.cursor() _email = request.form['email'] _pass = request.form['password'] # 调用存储过程,第三个参数为OUT参数占位符 cursor.callproc('iniciosesion', (_email, _pass, 0)) # 获取OUT参数的结果 cursor.execute("SELECT @_iniciosesion_2") # @_存储过程名_参数索引(从0开始,第三个参数索引为2) is_valid = cursor.fetchone()[0] # 生成响应 response = "Bienvenido" if is_valid == 1 else "Esta Cuenta no existe" # 关闭资源 cursor.close() return response
方式2:不修改存储过程,直接获取查询结果集
如果不想改动存储过程,可以在调用callproc()后,通过游标获取存储过程执行的SELECT结果:
@app.route('/iniciarsesion', methods=['POST']) def sessiousuario(): cursor = mysql.connection.cursor() _email = request.form['email'] _pass = request.form['password'] # 调用存储过程 cursor.callproc('iniciosesion', (_email, _pass)) # 获取SELECT返回的结果 result = cursor.fetchone() is_valid = result[0] if result else 0 # 生成响应 response = "Bienvenido" if is_valid == 1 else "Esta Cuenta no existe" # 关闭资源 cursor.close() return response
重要安全提示
永远不要明文存储用户密码,当前数据库中直接存储明文密码存在严重安全风险。建议使用bcrypt等哈希算法,存储密码的哈希值,验证时对用户输入的密码进行哈希后再与数据库中的值比较。
内容的提问来源于stack exchange,提问作者JMDG21
相关产品推荐
相关产品推荐

