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

Flask+SQLite登录验证报错:coercing to Unicode: sqlite3.Cursor found

问题根源:把游标对象当成查询结果使用

嘿,这个错误TypeError: coercing to Unicode: need string or buffer, sqlite3.Cursor found的原因一眼就能看出来——你直接把cur.execute()返回的游标对象赋值给了pwd、uname和salt变量,而不是从游标里提取实际的查询数据!游标本身只是一个指向结果集的"指针",不是你要的字符串或数值,当hash_password函数尝试把游标和密码拼接时,自然会触发Unicode转换错误。

另外,你的代码还有个严重的安全隐患:用字符串拼接SQL语句会招来SQL注入攻击,必须立刻改成参数化查询。


修正后的登录路由代码

我帮你重写了核心逻辑,同时修复了上述两个问题,还简化了冗余的查询操作:

@app.route('/login', methods=['POST', 'GET'])
def do_admin_login():
    if request.method == "POST":
        username = request.form['username']
        password = request.form['password']

        # 使用参数化查询彻底避免SQL注入
        with sql.connect("database.db") as con:
            cur = con.cursor()
            
            # 一次查询获取用户的密码哈希和盐值,减少数据库交互
            cur.execute("SELECT pword, salt FROM logins WHERE uname = ?", (username,))
            user_data = cur.fetchone()
            
            if not user_data:
                # 用户不存在,统一提示避免泄露信息
                flash('Wrong username or password!')
                return render_template('login.html')
            
            stored_pwd, salt = user_data
            
            # 验证密码
            hashed_password = hash_password(password, salt)
            if hashed_password == stored_pwd:
                session['logged_in'] = True
                flash('Right password!')
                return render_template('home.html')
            else:
                flash('Wrong username or password!')
                return render_template('login.html')
    else:
        return render_template('login.html')

关键修复点说明
  • 获取真实查询结果:用cur.fetchone()获取单条记录,它会返回一个元组(比如(存储的密码哈希, 盐值)),直接解构赋值就能拿到你需要的具体数据;如果用户不存在,fetchone()会返回None,我们可以直接判断并提示错误。
  • 参数化查询:把SQL里的变量用?占位,参数放在元组里传给execute(),既避免了SQL注入,也不用手动处理字符串转义的麻烦。
  • 简化逻辑:原来的三个查询合并成一个,减少数据库交互次数,提升性能。
  • 移除冗余操作:con.commit()和con.close()都不需要——with语句会自动管理连接的关闭,查询操作也不需要提交事务。

额外优化建议
  1. 给hash_password函数加个防御性判断,避免salt为空的情况:
def hash_password(password, salt):
    if not salt:
        raise ValueError("Salt cannot be empty")
    password_string = (password + salt).encode('utf-8')
    hashed_password = hashlib.sha512(password_string).hexdigest()
    return hashed_password
  1. 错误提示统一用"用户名或密码错误",不要区分两种情况,避免泄露用户存在性的敏感信息,提升账号安全性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:09:01