当我使用 If/Else 语句时按钮不工作

Button is not working when I used If/Else statement

我有一个用于用户名的组合框和一个用于密码的文本框。我正在尝试创建通常的登录表单,用户需要在其中输入正确的用户名和密码,否则访问将被拒绝。 MsgBox("Welcome") 正在工作,而 MsgBox("Failed") 没有。

Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
    sSql = "Select * from tblusers where username = '" & cmbusers.Text & "' and password = '" & txtpass.Text & "'"
    execSQL(sSql, False)
    If RD.Read Then
        If cmbusers.Text = RD(1) And txtpass.Text = RD(2) Then
            MsgBox("Welcome")
        Else
            MsgBox("Failed", MsgBoxStyle.Critical)
        End If
    End If
End Sub

如果凭据不正确,您的查询将不会 return 任何内容,您的 messageBox Failed 位于错误的位置,因为它只有在读取数据时才会出现。

Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
    sSql = "Select * from tblusers where username = '" & cmbusers.Text & "' and password = '" & txtpass.Text & "'"
    execSQL(sSql, False)
    If RD.Read Then
        If cmbusers.Text = RD(1) And txtpass.Text = RD(2) Then
            MsgBox("Welcome")
        End If
    Else
        MsgBox("Failed")
    End If
End Sub

检查用户名和密码是否分开

正如 Youssef13 所指出的,您的查询指定了用户名和密码,然后您也检查了两者的结果。如果密码或用户名错误,查询将不会 return 任何结果并且 RD.Read 将是 false。我建议先验证用户名,然后再验证密码。应该通知用户哪一个是错误的,因为这对登录可用性至关重要。

Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
    sSql = "Select * from tblusers where username = '" & cmbusers.Text & "'"
    execSQL(sSql, False)
    'Assume we have one record because usernames are unique, can we assume this?
    If RD.Read Then
        If txtpass.Text = RD(2) Then
            MsgBox("Welcome")
        Else
            MsgBox("Bad Password", MsgBoxStyle.Critical)
        End If
    Else
        MsgBox("Bad Username", MsgBoxStyle.Critical)
    End If
End Sub

SQL 注入、处置和其他改进

下面的代码显示了如何使用参数 avoid sql injection, using statements for proper object disposaltry/catch 用于 reader 异常,以及列名而不是索引(不太容易被无意中破坏)。

Private Sub btnlogin_Click(sender As Object, e As EventArgs) Handles btnlogin.Click
    Using MySQLConnection As New SqlConnection("<Connection String Here>")
        MySQLConnection.Open()
        Using cmd As New SqlCommand("Select * from tblusers where username = @Username", MySQLConnection)
            cmd.Parameters.Add("Username", SqlDbType.Text).Value = cmbusers.Text
            Try
                Using RD = cmd.ExecuteReader()
                    If RD.Read Then
                        If RD("<NameOfPasswordColumnHere>") = txtpass.Text Then
                            MsgBox("Welcome")
                        Else
                            MsgBox("Bad Password", MsgBoxStyle.Critical)
                        End If
                    Else
                        MsgBox("Bad Username", MsgBoxStyle.Critical)
                    End If
                End Using
            Catch ex As InvalidCastException
                'Handling Not implemented, throw exception
                Throw
            Catch ex As SqlException
                'Handling Not implemented, throw exception
                Throw
            Catch ex As InvalidOperationException
                'Handling Not implemented, throw exception
                Throw
            Catch ex As ObjectDisposedException
                'Handling Not implemented, throw exception
                Throw
            Catch ex As IOException
                'Handling Not implemented, throw exception
                Throw
            Catch ex As NullReferenceException
                'Handling Not implemented, throw exception
                Throw
            End Try
        End Using
    End Using
End Sub

密码安全

此外,您似乎在存储纯文本密码,应该避免这种情况。即使是一个简单的 XOR 密码(如下所示)也是一种改进。有些人可能会争辩说这给人一种错误的安全感,但总比没有好。您可以跟进 SQLhashing 以及许多其他改进,但不要害怕从一些小的安全步骤开始。例如,TextBox1.UseSystemPasswordChar = TrueSecureString.

等基本预防措施
Private Function XORString(Text As String, Key As String, Enc As System.Text.Encoding) As String

    Dim TextBytes() As Byte
    Dim KeyBytes() As Byte
    Dim TextByteCount As Long
    Dim KeyByteCount As Long
    Dim KeyIdx As Long
    Dim TextIdx As Long

    TextBytes = Enc.GetBytes(Text)
    KeyBytes = Enc.GetBytes(Key)
    TextByteCount = UBound(TextBytes)
    KeyByteCount = UBound(KeyBytes)

    For TextIdx = 0 To TextByteCount
        TextBytes(TextIdx) = TextBytes(TextIdx) Xor KeyBytes(KeyIdx)
        If KeyIdx < KeyByteCount Then
            KeyIdx += KeyIdx
        Else
            KeyIdx = 0
        End If
    Next TextIdx

    XORString = Enc.GetString(TextBytes)
End Function

这样使用...

'Other code here ... 
Using RD = cmd.ExecuteReader()
    If RD.Read Then
        'RD("NameOfPasswordColumn") must contain an XORed value set from XORString("<UsersSavedPassword>", "ThisIsBetterThanNothing", <Correct Encoding Here>)
        If XORString(RD("NameOfPasswordColumn"), "ThisIsBetterThanNothing", System.Text.Encoding.Unicode) = txtpass.Text Then
            MsgBox("Welcome")
        Else
            MsgBox("Bad Password", MsgBoxStyle.Critical)
        End If
    Else
        MsgBox("Bad Username", MsgBoxStyle.Critical)
    End If
End Using
'... rest of code