【问题标题】:VB.NET DataTable rowsVB.NET 数据表行
【发布时间】:2018-11-28 17:01:41
【问题描述】:

我正在尝试制作登录表单。

我在我的服务器上创建了一个数据库并创建了行用户名和密码。 然后我创建了一个 root 用户,密码为 root。

但是我在检查用户名和密码是否正确时遇到了问题, 我不知道如何给他 2 行。

Dim conn = New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user")
Dim sda = New SqlDataAdapter("select count(*) from tblLogin where username ='" + txtUsername.Text + "' and password='" + txtUserPwd.Text + "'", conn)
Dim dt = New DataTable()
sda.Fill(dt)
If (dt.Rows().ToString() = "1") Then
    MsgBox("Logged-in successfully")
Else
    MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If

表格:

【问题讨论】:

  • 哇!!!你那里有很多问题。首先"username ='" + txtUsername.Text + "'"。这不是参数化查询,考虑到您正在运行的语句,txtUsername 的值来自用户输入。这是可以注入的。你现在需要解决这个问题。 参数化您的查询。接下来我们有"password='" + txtUserPwd.Text + "'";这 非常强烈 意味着您将密码存储为纯文本。除此之外,这也对注入开放从不将密码存储为纯文本。理想情况下,它们应该经过哈希处理和加盐处理。
  • 举一个非常简单的例子,如果有人输入他们的用户名'; SELECT * FROM sys.tables; DROP TABLE tblLogin;--' CREATE LOGIN SuperAdmin WITH PASSWORD= '123', CHECK_POLICY=OFF, CHECK_EXPIRY = OFF; ALTER SERVER ROLE [sysadmin] ADD MEMBER [SuperAdmin];--,你认为会发生什么?
  • 这只是一个我正在制作的有趣的项目,所以我不会在任何地方上传它,它甚至是我的第一个 SQL 项目
  • If (dt.Rows().ToString() = "1" 并不表示使用您正在使用的查询成功登录。该行的值可以是 1 或 0。在任何一种情况下,您总是会得到一行。您需要查看返回的实际值,而不仅仅是行数。如果您想通过简单的行数进行检查,那么您需要SELECT * FROM tblLogin WHERE username=...。或者更好,SELECT 1 FROM tblLogin WHERE username=...
  • @squillman 我看不出 OP Select 语句有什么问题(除了它需要使用参数)。选择 * 会减少不必要的数据。

标签: sql-server database vb.net login


【解决方案1】:

在线评论和解释。

Private Sub VerifyLogin()
        'For the Return Value of the command
        Dim RetVal As Integer
        ' A Using...End Using will ensure that you connectionis closed and disposed event
        'it there is an error.
        Using conn = New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user")
            'You don't need a DataAdapter, just a command
            'USE PARAMETERS. Yes, I am yelling :-) Even if you are the only user
            'it will save you headaches with syntax.
            Using cmd = New SqlCommand("select count(*) from tblLogin where username = @UserName and password= @Password;", conn)
                cmd.Parameters.Add("@UserName", SqlDbType.VarChar).Value = txtUsername.Text
                cmd.Parameters.Add("@Password", SqlDbType.VarChar).Value = txtUserPwd.Text
                'You are only returning one row
                'ExecuteScalar returns the value in the first column of the 
                'first row of the the data
                conn.Open()
                RetVal = CInt(cmd.ExecuteScalar)
            End Using
        End Using
        'No need to convert to a string just compare the Integer
        If RetVal = 1 Then
            MsgBox("Logged-in successfully")
        Else
            MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End If
End Sub

【讨论】:

    【解决方案2】:
    Private Function CalculateHash(password As String, salt As String) As String
        'TODO:
        ' Suggest pulling the BCrypt from the NuGet gallery for this:
        ' https://www.nuget.org/packages/BCrypt-Official/
        ' Just remember that bcyrpt lib encodes salt as part of the password hash, so the function signatures and db table will be different.
    End Function
    
    Public Function CheckCredentials(UserName As String, Password As String) As Boolean
        Using conn As New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user"), _
              ' Need to add a "Salt" column to your table, create a new random salt for each user when you create the user
              cmd As New SqlCommand("SELECT Salt, PwdHash FROM tblLogin WHERE username = @Username", conn)
    
            'Parameterized queries or NOTHING. String concatention is NOT OKAY here
            cmd.Parameters.Add("@UserName", SqlDbType.NVarChar, 50).Value = UserName
    
            conn.Open()   
            Using rdr As SqlDataReader = cmd.ExecuteReader()
                If Not rdr.Read() Then Return False
    
                Dim Salt As String = rdr("Salt")
                Dim PwdHash As String = rdr("PwdHash")
    
                'Compare HASHES, not Passwords
                Return PwdHash = CalculateHash(Password, Salt As String)
            End Using
        End Using
    End Function
    
    If CheckCredentials(txtUsername.Text, txtUserPwd.Text) Then
        MsgBox("Logged-in successfully")
    Else
        MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
    End If
    

    【讨论】:

      【解决方案3】:

      改用 DataReader,使用此代码,只需在登录按钮或其他地方调用 CheckLogin。

      Sub CheckLogin()
      
          Dim conn = New SqlConnection("Data Source=SRV-SQL;Initial Catalog=prova;User ID=user;Password=user")
      
          conn.Open()
      
          Try
      
              Dim query As String = "select count(*) from tblLogin where username = @username and password= @password "
              Dim cmd = New SqlCommand(query, conn)
              cmd.Parameters.AddWithValue("@username", txtUsername.Text)
              cmd.Parameters.AddWithValue("@password", txtUserPwd.Text)
              Dim DR As SqlDataReader = cmd.ExecuteReader()
      
              If DR.HasRows Then
      
                  MsgBox("Logged-in successfully")
      
              Else
      
                  MessageBox.Show("The username or the password is wrong!", "Warning!", MessageBoxButtons.OK, MessageBoxIcon.Error)
      
              End If
      
          Catch ex As Exception
              MsgBox(ex.Message)
          End Try
      
          conn.Close()
      
      End Sub
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-20
        • 2011-10-03
        • 2011-07-11
        相关资源
        最近更新 更多