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

VB项目表单重置密码无更新且无报错问题求助

密码重置功能无法更新SQLite数据库的问题排查与修复

问题概述

Visual Basic项目中,密码重置流程存在异常:验证用户名和重置关键词匹配后,密码输入框正常启用,但点击重置按钮后,SQLite数据库中的密码值未更新,且无任何错误提示。已尝试手动关闭数据库连接、添加SQLite异常捕获,问题仍未解决。

核心问题分析

从提供的代码来看,导致无反应的主要原因有以下几点:

  • 重置时的Hash值不匹配:点击重置按钮时会重新计算hash_reset,此时依赖的重置关键词输入框内容可能已被修改,导致UPDATE语句的WHERE条件无法匹配数据库记录,执行后无行受影响,也不会触发异常。
  • 字符串拼接SQL的隐患:直接用字符串拼接生成SQL语句,若用户名或密码包含单引号等特殊字符,会导致SQL语法错误,但仅捕获SQLiteException无法覆盖所有错误场景。
  • 未检查更新执行结果:ExecuteNonQuery()返回受影响行数,若返回0说明无匹配记录,但当前代码未做判断,用户无法得知操作失败原因。
  • 密码明文存储:新密码直接以明文存入数据库,不符合安全规范,应和重置关键词一样用SHA512加密。
  • 资源未正确释放:验证方法中的SQLiteDataReader未用Using块包裹,可能导致资源泄漏。

修复后的完整代码

Imports System.Data.SQLite
Imports System.Security.Cryptography
Imports System.Text

Public Class resetar_pass
    ' 验证成功后保存有效的用户名和Hash值,避免重置时重新计算导致不匹配
    Private validUsername As String = String.Empty
    Private validResetHash As String = String.Empty
    Dim encriptacao_SHA512 As SHA512 = SHA512.Create()

    Private Sub resetar_pass_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' 初始隐藏密码输入框
        TextBox2.Visible = False
        TextBox3.Visible = False
    End Sub

    ' 通用加密方法,可复用
    Private Function EncriptarValor(valor As String) As String
        Dim valorHash As Byte() = encriptacao_SHA512.ComputeHash(Encoding.UTF8.GetBytes(valor))
        Return Convert.ToBase64String(valorHash)
    End Function

    Private Sub verificar(sender As Object, e As MouseEventArgs) Handles MyBase.MouseClick
        ' 清空之前的验证信息
        validUsername = String.Empty
        validResetHash = String.Empty

        Using connection As New SQLiteConnection(connectionString)
            Try
                connection.Open()
                Dim inputUsername As String = UsernameTextBox.Text.Trim()
                Dim inputResetKey As String = TextBox1.Text.Trim()

                ' 计算输入的重置关键词Hash
                Dim resetHash As String = EncriptarValor(inputResetKey)

                ' 使用参数化查询,避免SQL注入并保证参数正确
                Dim query As String = "SELECT username FROM login WHERE username = @Username AND reset = @ResetHash;"
                Using command As New SQLiteCommand(query, connection)
                    command.Parameters.AddWithValue("@Username", inputUsername)
                    command.Parameters.AddWithValue("@ResetHash", resetHash)

                    Using reader As SQLiteDataReader = command.ExecuteReader()
                        If reader.HasRows Then
                            ' 验证成功,保存有效的用户名和Hash值
                            reader.Read()
                            validUsername = reader("username").ToString()
                            validResetHash = resetHash
                            TextBox2.Visible = True
                            TextBox3.Visible = True
                        Else
                            MessageBox.Show("用户名或重置关键词错误!")
                        End If
                    End Using
                End Using
            Catch ex As Exception
                MessageBox.Show($"验证出错:{ex.Message}")
            End Try
        End Using
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' 先检查是否已通过验证
        If String.IsNullOrEmpty(validUsername) OrElse String.IsNullOrEmpty(validResetHash) Then
            MessageBox.Show("请先完成用户名和重置关键词的验证!")
            Return
        End If

        Dim novaSenha As String = TextBox2.Text.Trim()
        Dim confirmarSenha As String = TextBox3.Text.Trim()

        If novaSenha <> confirmarSenha Then
            MessageBox.Show("两次输入的密码不匹配!")
            Return
        End If

        ' 加密新密码
        Dim senhaHash As String = EncriptarValor(novaSenha)

        Using connection As New SQLiteConnection(connectionString)
            Try
                connection.Open()
                ' 参数化更新语句
                Dim updateQuery As String = "UPDATE login SET password = @PasswordHash WHERE username = @Username AND reset = @ResetHash;"
                Using command As New SQLiteCommand(updateQuery, connection)
                    command.Parameters.AddWithValue("@PasswordHash", senhaHash)
                    command.Parameters.AddWithValue("@Username", validUsername)
                    command.Parameters.AddWithValue("@ResetHash", validResetHash)

                    Dim linhasAfetadas As Integer = command.ExecuteNonQuery()
                    If linhasAfetadas > 0 Then
                        MessageBox.Show("密码重置成功!")
                        ' 重置界面状态
                        validUsername = String.Empty
                        validResetHash = String.Empty
                        UsernameTextBox.Clear()
                        TextBox1.Clear()
                        TextBox2.Clear()
                        TextBox3.Clear()
                        TextBox2.Visible = False
                        TextBox3.Visible = False
                    Else
                        MessageBox.Show("密码重置失败,未找到匹配的用户记录!")
                    End If
                End Using
            Catch ex As Exception
                MessageBox.Show($"重置密码出错:{ex.Message}")
            End Try
        End Using
    End Sub
End Class

关键修复点说明

  • 保存验证状态:验证成功后存储有效的用户名和重置关键词Hash,避免重置时重新计算导致不匹配。
  • 参数化查询:彻底避免SQL注入问题,确保特殊字符不会破坏SQL语句结构。
  • 通用加密方法:统一处理重置关键词和密码的加密,保证逻辑一致。
  • 扩大异常捕获范围:捕获所有Exception,确保任何错误都能被提示。
  • 检查更新结果:通过ExecuteNonQuery()的返回值判断是否成功更新,给用户明确反馈。
  • 资源正确释放:所有SQL命令和DataReader都用Using块包裹,自动释放资源。
  • 安全存储密码:新密码同样用SHA512加密后存入数据库。

验证建议

  1. 测试时可以输出linhasAfetadas的值,确认是否有行被修改。
  2. 检查数据库中login表的reset字段值,确保和验证时计算的Hash一致。
  3. 测试包含特殊字符(如单引号、空格)的用户名和密码,确认参数化查询能正常处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 18:54:56