2016-04-06 5 views
0

Я пытаюсь создать регистр для использования таблицы mysql, как если бы имя пользователя и пароль уже были добавлены, он выдает сообщение msgbox, в котором вы уже зарегистрированы, но случается, что он всегда добавляет его, даже если он уже существует ..Проверка, что пользователь уже зарегистрирован

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click 
    Dim cn As New SqlConnection 
    Dim cmd As New SqlCommand 
    Dim cmd2 As New SqlCommand 
    Dim dr As SqlDataReader 
     cn.ConnectionString = "Server=localhost;Database=test;Uid=sa;Pwd=fadyjoseph21" 
     cmd.Connection = cn 
    cmd.CommandText = "INSERT INTO test2(Username,Password) VALUES('" & TextBox1.Text & "','" & TextBox2.Text & "')" 
    cmd2.CommandText = cmd.CommandText = "SELECT username, password FROM test2 WHERE username = '" & TextBox1.Text & "' and password = '" & TextBox2.Text & "'" 
    cn.Open() 
    MsgBox("Registered") 
    cmd.ExecuteNonQuery() 
    dr = cmd.ExecuteReader 
    If dr.HasRows Then 
     MsgBox("You're already registered") 
    End If 
End Sub 

End Class

+3

Do not Concat строки для создания SQL. Используйте SQL-параметры. Ваш код будет разбит на все виды ирландских и французских имен (например: «Майк О'Тул», «Джоан Д'Арк») и уязвим для SQL-инъекции. Не хранить пароли как открытый текст; хэш и солить их. Это все, что вам нужно от нового пользователя, это имя и PW? Нет электронной почты? Нет вопроса о восстановлении PW? – Plutonix

+0

В дополнение к тому, что написал Plutonix: 1) Вам нужно только проверить, находится ли имя пользователя уже в базе данных. 2) Вы не должны использовать 'cmd.ExecuteNonQuery()' до тех пор, пока не проверите, существует ли имя пользователя. 3) Кажется, вы используете 'cmd' вместо' cmd2' для выполнения проверки. –

+0

Mmm. Хеш и соль. –

ответ

0

Добавить уникальное ключевое ограничение на имя пользователя и, следовательно, когда он уже существует, то он будет бросать исключение дублирования ввода.

Во-вторых, никогда не сохраняйте пароль обычного текста в базе данных, он должен быть hasheh и зашифрован. Я бы предложил лучше использовать Bcrypt по крайней мере 10 уровня, чтобы генерировать хешированный пароль, а также использовать динамическую соль Bcrypt, которая в настоящее время наиболее предпочтительна.

В-третьих, всегда используйте параметризованный запрос, чтобы избежать вашей программы из mysql-инъекции. Например: -

Normal:

SELECT * FROM customers WHERE username = 'timmy' 

Injection:

SELECT * FROM customers WHERE username = '' OR 1'' 
1

Вы никогда не проверить, если имя пользователя существует.

Вы определяете запрос здесь:

cmd2.CommandText = cmd.CommandText = "SELECT username, password FROM test2 WHERE username = '" & TextBox1.Text & "' and password = '" & TextBox2.Text & "'" 

Но никогда не выполнить этот запрос. Вместо этого, вы просто выполнить INSERT запрос:

dr = cmd.ExecuteReader 

Так INSERT всегда выполняется. А так как INSERT не возвращает строки, вы не видите окно сообщения.


Первое сначала, исправить инъекции SQL уязвимость. (Абонентский политик, я не люблю писать SQL-инъекции коды в ответе.) Используйте параметры запроса, а не непосредственно конкатенации пользовательского ввода, как код:

cmd2.CommandText = "SELECT * FROM test2 WHERE username = @Username" 
cmd2.Parameters.Add("@Username", SqlDbType.VarChar, 50).Value = TextBox1.Text 
dr = cmd2.ExecuteReader 
If dr.HasRows Then 
    MsgBox("You're already registered") 
    Return 
End If 

Примечания нескольких вещей здесь:

  • Использование параметра запроса. Я должен был догадываться о типе и размере столбца в базе данных, при необходимости отрегулировать его.
  • Только выполнение этого одного запроса. Не пытайтесь выполнить оба запроса одновременно, выполните первый, а затем выполните второй.
  • Вам не нужно, или даже хочу, чтобы включить пароль в этот запрос. Вы проверяете, существует ли уже имя пользователя, вот и все.
  • Return после показа сообщения, поэтому остальная часть функции не выполняется.

Тогда, после этого не будет сделано, вы можете выполнить операцию INSERT:

cmd.CommandText = "INSERT INTO test2(Username,Password) VALUES(@Username,@Password)" 
cmd.Parameters.Add("@Username", SqlDbType.VarChar, 50).Value = TextBox1.Text 
cmd.Parameters.Add("@Password", SqlDbType.VarChar, 50).Value = TextBox2.Text 
cmd.ExecuteNonQuery() 

Это будет выполнять INSERT операцию. Поэтому, если Return выше никогда не встречался, имя пользователя уникально и может быть вставлено.


также: Вы должны не быть хранения пользовательских паролей в виде простого текста. Это грубо безответственно вашим пользователям и предоставляет свои личные данные злоумышленникам. Вместо этого obscure the password with a one-way hash так, чтобы он не мог быть в оригинальном формате.


пара другие вещи:

  • Используйте осмысленные имена переменных. Вся причина, по которой вы столкнулись с этой проблемой, состояла в том, что вы путались между cmd и cmd2. Если ваши имена переменных имеют семантический смысл, ваш код намного легче читать и понимать.
  • Использовать the Using block, если у вас есть ресурсы, такие как подключение к базе данных. В общем, вы хотите открыть, использовать и закрыть соединение с базой данных как можно малым объемом. Оставляя открытые соединения, висящие вокруг, это Bad Thing.
Смежные вопросы