Private Sub BtnLogin_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnLogin.Click
Dim sql As String
sql = " SELECT * FROM LoginDetails WHERE UsernameID = '" & TxtUsername.Text & "' AND Password = '" & TxtPassword.Text & "'"
ds = db.sqlSelect(sql)
Dim i As Integer
Dim Username As String = ds.Tables("LoginDetails").Rows(i)("UsernameID")
Dim Password As String = ds.Tables("LoginDetails").Rows(i)("Password")
''''''STUDENT LOGIN'''''''
If TxtUsername.Text = "" And TxtPassword.Text = "" Then
MsgBox("No username and password entered!")
ElseIf TxtUsername.Text = "" Then
MsgBox("No username entered!")
ElseIf TxtPassword.Text = "" Then
MsgBox("No password entered!")
End If
Username = TxtUsername.Text.ToLower
Password = TxtPassword.Text.ToLower
If TxtUsername.Text.ToLower = Username And TxtPassword.Text = Password Then
FrmMainMenu.Show()
Me.Hide()
FrmMainMenu.LblWelcome.Text = "Welcome " & ds.Tables("LoginDetails").Rows(i)("Student Name") & "!"
ElseIf TxtUsername.Text.ToLower = Username And TxtPassword.Text <> Password Then
MsgBox("Wrong password entered!")
End If
If TxtUsername.Text.ToLower <> Username And TxtPassword.Text <> Password Then
MsgBox("Wrong password or username!")
Else
End If
If Len(Username) <> 7 Then
MsgBox("Username must be exactly 7 characters long and must be in the following format: 1XlXXXX")
End If
If Len(Password) < 6 And Len(Password) > 30 Then
MsgBox("Password must be between 6 and 30 characters!")
End If
When I type in the correct details for the form it works, but whenever I type in say a wrong password, it crashes!
Can anyone help me solve this?? I keep getting this error!!!
IndexOutofRangeException was unhandled
There is no row at position 0.
Pointing at the code: Dim Username As String = ds.Tables("LoginDetails").Rows(i)("UsernameID")
Here is the class that links the code to my database:
Imports System.Data.OleDb
Public Class clsDBConnector
Dim con As New OleDbConnection
Dim dbProvider As String
Dim dbSource As String
Dim da As OleDbDataAdapter
Dim ds As New DataSet
Sub connect()
dbProvider = "PROVIDER=MICROSOFT.ACE.OLEDB.12.0;"
dbSource = "Data Source = E:\Computing\COMP4\Database.accdb "
con.ConnectionString = dbProvider & dbSource
con.Open()
End Sub
Function sqlSelect(ByVal sqlString As String)
da = New OleDbDataAdapter(sqlString, con)
da.Fill(ds, "LoginDetails")
Return ds
End Function
Sub reset()
ds.Reset()
End Sub
Sub SQLinsert(ByVal sql) 'inserts data into database
Dim da As New OleDbCommand(sql, Con)
da.ExecuteNonQuery()
End Sub
Function SQLupdate(ByVal sqlString As String)
da = New OleDbDataAdapter(sqlString, con)
da.Fill(ds, "LoginDetails")
Return ds
End Function
End Class
The first thing you're doing wrong is storing plain-text passwords. Never store plain-text passwords.
The second thing is that you're wide open to SQL injection attack. Use parameterized queries. Otherwise you're allowing users to arbitrarily execute any code they'd like on your database.
The third thing is that you're assuming a returned value here:
sql = " SELECT * FROM LoginDetails WHERE UsernameID = '" & TxtUsername.Text & "' AND Password = '" & TxtPassword.Text & "'"
ds = db.sqlSelect(sql)
Dim i As Integer
Dim Username As String = ds.Tables("LoginDetails").Rows(i)("UsernameID")
Dim Password As String = ds.Tables("LoginDetails").Rows(i)("Password")
If that SELECT statement doesn't find any values, then Rows(i) (i is 0 in this case since that's the default for an Integer) doesn't exist. You need to check the count of Rows before trying to access it. In this case, logically, if Rows.Count is 0 then no match was found for the username/password combination, so the login fails. Notify the user that the login has failed and stop executing anything else.
The fourth thing you're doing wrong is storing plain-text passwords. Never store plain-text passwords.
Before you start using the dataset after the SQL call you should alway check to see if you received valid/any data back . Call a DataSet check method like the one I included. If it returns false you know your SQL returned an empty DataSet. So you can display a message stating invalid login info..
bool IsEmpty(DataSet dataSet)
{
foreach(DataTable table in dataSet.Tables)
{ if (table.Rows.Count != 0) return false; }
return true;
}
Every time you try to take information from the DB, with something like:
If ds.tables("MyTable").rowsCount > 0 then
// Do the stuff
Else
// There is no information on the table
End If
Related
Okay I have created a log in system on VB.net using a database on access. The problem I am having is that some of the username and password combinations work perfectly, but some of them, although put in correctly, don't work at all. This is the code I have written...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' Check if username or password is empty
If textpassword.Text = "" Or textusername.Text = "" Then
MessageBox.Show("Please complete the required fields..", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
' Both fields were supplied
' Check if user exist in database
' Connect to DB
Dim conn As New System.Data.OleDb.OleDbConnection()
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\database1.accdb"
'conn.Open()
'MsgBox("Susscess")
Dim sql As String = "SELECT * FROM Accounts WHERE username='" & textusername.Text & "' AND password = '" & textpassword.Text & "'"
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
'Open Database Connection
sqlCom.Connection = conn
conn.Open()
Dim sqlRead As System.Data.OleDb.OleDbDataReader = sqlCom.ExecuteReader()
If sqlRead.Read() Then
MemberPage.Show()
Me.Hide()
Else
' If user enter wrong username and password combination
' Throw an error message
MessageBox.Show("Username and Password do not match..", "Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
'Clear all fields
textpassword.Text = ""
textusername.Text = ""
'Focus on Username field
textusername.Focus()
End If
End If
End Sub
Do not Concatenate string.Its wide open for SQL injection .Its better to use Parameterized query
Dim sql As String = "SELECT * FROM Accounts WHERE username=? AND password = ?"
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
sqlCom.Parameters.AddWithValue("?", textusername.Text);
sqlCom.Parameters.AddWithValue("?", textpassword.Text);
Also you can use HasRows property
If sqlRead.HasRows Then
While sqlRead.Read()
MemberPage.Show()
Me.Hide()
End While
Else
MessageBox.Show("Username and Password do not match..", "Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation) 'Clear all fields
textpassword.Text = ""
textusername.Text = ""
'Focus on Username field
textusername.Focus()
End If
It seems that some mistake is happening at the condition you checking after filling the dataReader. i.e
If sqlRead.Read() Then
try the if condition by following code
If Not sqlRead Is Nothing Then
if it doesnt work then..
I would suggest you to do it using DataAdapter and check whether it returns rows. if the row count is greater than 1 , you must show the MemberPage
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If textpassword.Text = "" Or textusername.Text = "" Then
MessageBox.Show("Please complete the required fields..", "Authentication Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
Dim conn As New System.Data.OleDb.OleDbConnection()
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=|DataDirectory|\database1.accdb"
Dim sql As String = "SELECT * FROM Accounts WHERE username='" & textusername.Text & "' AND password = '" & textpassword.Text & "'"
Dim sqlCom As New System.Data.OleDb.OleDbCommand(sql)
Dim ds As DataSet
sqlCom.Connection = conn
conn.Open()
'Dim sqlRead As System.Data.OleDb.OleDbDataReader = sqlCom.ExecuteReader()
Dim da as New OleDbDataAdapter(sqlCom)
da.Fill(ds)
If ds.Tables(0).Rows.Count > 1 Then
MemberPage.Show()
Me.Hide()
Else
MessageBox.Show("Username and Password do not match..", "Authentication Failure", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
textpassword.Text = ""
textusername.Text = ""
textusername.Focus()
End If
End If
End Sub
I'm a few day's searching for a problem, but can't find the answer. They are 1000 examples on youtube "how to make a login frm" but not in VB 2012 are by useing a selfmade database in VB.
So I already have a Bindingsource, Tableadapter, TableAdapterManager and a DatabaseDataSet en working with an tablegrid. Now I want to login to the system first before I get acces to the other parts of the program. The user have to write his name in to a textbox and when his names is existing (in the database), he get acces.
My problem is to check the column "users". What code can I use for that pleas?
Ideally You want the user to enter his/her username and password FIRST and then in the btnSubmit_Click event you should query the data source NEXT and check if the results are valid.
It is not recommended to load all the usernames/passwords and then look for a match.
It is `better/safer' to query ONLY for the single username/password pair.
This is not the EXACT code, but something along these lines.
Private Sub Submit_Click(sender As System.Object, e As System.EventArgs) Handles Submit.Click
'
If Trim(UsernameTextBox.Text) <> "" Then
If Trim(PasswordTextBox.Text) <> "" Then
'--> Query database here <--
'SELECT * From MyUsersSqlTable WHERE dbUsername='" trim(usernametextbox.text) & "' AND dbPassword='" & trim(passwordtextbox.text) & "'"
'If VALID Then
' Do something
'Else
' MsgBox("Error - Invalid login credentials")
' Do something else
'End If
Else
MsgBox("Error - No password entered")
End If
Else
MsgBox("Error - No username entered")
End If
'
End Sub
Obviously, you would not DIRECTLY enter the user entered data into a query, you should use parameters or VALIDATE the data to ensure it cannot inject something into your script!
You can check the username and password entered by the user with your table records. If both the fields match, it logins otherwise throws a message. However, you might also need to check case-sensitive password.
You can refer the following code.
Protected Sub SignIn(sender As Object, e As EventArgs) Handles btnsignin.ServerClick
Dim last_login As String
last_login = Now.Date.ToString("dd/MM/yy")
Try
conn.Close()
conn.Open()
Dim cmd As New MySqlCommand
cmd.CommandText = "SELECT * FROM user WHERE user_email = ('" & txtemail.Value.ToString & "') AND user_password=('" & txtpassword.Value.ToString & "') COLLATE utf8_bin"
cmd.Connection = conn
Dim da As New MySqlDataAdapter
Dim ds As New DataSet
da.SelectCommand = cmd
da.Fill(ds)
txtemail.DataBind()
txtpassword.DataBind()
Dim usercount = ds.Tables(0).Rows.Count
If usercount = 1 Then
reader = cmd.ExecuteReader
Session("user_email") = txtemail.Value.ToString
If reader.Read Then
Session("user_name") = reader.Item("user_name").ToString
'SetUserName(user_name)
Session("last_login") = reader.Item("last_login").ToString
str = "UPDATE user SET last_login = ('" & last_login.ToString & "') WHERE user_email = ('" & txtemail.Value.ToString & "') "
cmd = New MySqlCommand(str, conn)
reader.Close()
cmd.ExecuteNonQuery()
End If
Else
MsgBox("Incorrect email or password", MsgBoxStyle.Exclamation)
Return
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
conn.Close()
End Sub
I am making a create an account system, and in this I am using a SELECT * FROM query to read all of the data in the database to see if the inputted username already exists however this is only returning the very last user in the database, so if the inputted user matches any other user excluding the last saved account, it will not recognize that the user already exists therefore creating an account with the same username. Below is my code for the sub routine. can anyone please help me find what I have done wrong
Dim conn As New OleDbConnection
Dim myqry As String = Nothing
Dim mycmd As New OleDbCommand
Dim mydr As OleDbDataReader
Private Sub btn_createAccount_Click(sender As System.Object, e As System.EventArgs) Handles btn_createAccount.Click
'Connecting to the database
Try
With conn
If .State = ConnectionState.Open Then .Close()
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=Database.accdb"
.Open()
End With
Catch ex As Exception
MessageBox.Show("Unable to connect", "error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Dim student_Name As String
Dim student_Username As String
Dim student_Password As String
Dim student_Group As String
student_Name = txt_firstname.Text & " " & txt_surname.Text
student_Username = LCase(txt_Username.Text)
student_Password = txt_password.Text
student_Group = cbo_tutorGroup.SelectedItem
'This chunk of code is reading the username column in the student account table in my database and doing a read to see if the inputted username is already existent in the table.
myqry = "SELECT * FROM TblStudents"
mycmd = New OleDbCommand(myqry, conn)
mydr = mycmd.ExecuteReader
While mydr.Read
Dim user As String = mydr("studentUser").ToString
If user = student_Username Then
MsgBox("Username already exists, please choose another")
Else
'If the username is not taken, the account credentials will be stored for use when logging in
Dim sqlQry As String
sqlQry = "INSERT INTO TblStudents(studentName, tutorGroup, studentUser, studentPass) VALUES('" & student_Name & "','" & student_Group & "','" & student_Username & "','" & student_Password & "')"
Dim cmd As New OleDbCommand(sqlQry, conn)
cmd.ExecuteNonQuery()
MsgBox("Your account has successfully been created")
Login_Student.Show()
Me.Close()
Exit Sub
End If
End While
I think you are misinterpreting your results. The query may return many rows but if the first one does not match your condition (user = student_Username), then you insert a record and exit the procedure.
Why don't you check if your specific user exists:
SELECT * FROM TblStudents WHERE studentUser = :student_Username
instead of checking each student?
How can I convert a row data into string or text and display it into a label? My problem is when I click on my login button which contains the SQL code that gains a row data into alabel, the result in my label is false. not the text. How can I convert it into string?
Here's my code:
Private Sub cmdLog_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdLog.Click
Dim connection As New SqlClient.SqlConnection
Dim command As New SqlClient.SqlCommand
Dim adaptor As New SqlClient.SqlDataAdapter
Dim dataset As New DataSet
Dim reader As MySqlDataReader = Nothing
Dim sapi
sapi = CreateObject("sapi.spvoice")
connection.ConnectionString = ("Data Source=.\SQLEXPRESS;AttachDbFilename=C:\Users\Calupad\Desktop\HTF feat Yiyet\HTF feat Yiyet\Database1.mdf;Integrated Security=True;User Instance=True")
command.CommandText = "SELECT * FROM [Users] WHERE Username='" & txtUser.Text & "' AND Password ='" & txtPass.Text & "';"
txtWel.Text = "Welcome Back, " + txtUser.Text + "!....."
connection.Open()
command.Connection = connection
adaptor.SelectCommand = command
adaptor.Fill(dataset, "0")
txtStat.text = command.CommandText = "SELECT Status FROM [Users] WHERE Username = '" & txtUser.Text & "' ".ToString
txtStat.Text = stat
Dim count = dataset.Tables(0).Rows.Count
If count > 0 Then
MsgBox("Login Successful!" & vbNewLine & txtStat.Text, MsgBoxStyle.Information, "Access Granted")
sapi.speak(txtWel.Text)
Me.Hide()
Form1.Show()
frmMenu.Show()
txtUser.Clear()
txtPass.Clear()
tries = 3
Else
ctr = tries - 1
tries = ctr
sapi.speak(txtUser.Text + txtNot.Text)
MsgBox("Invalid Account!" + vbNewLine + "Attempts Remaining: " & tries, vbCritical, "Access Denied")
txtUser.Clear()
txtPass.Clear()
If tries = 0 Then
MsgBox("You've reached the maximum attempts!" + vbNewLine + "The program will be terminated.", vbCritical, "Terminated!")
Me.Close()
End If
End If
End Sub
First of all, the way you check for username and password is weak and is most certainly volnurable to SQL injections. You are checking if the 'count' of rows is greater than zero then the user has logged in successfully, where as you should only compare count to 1. and instead of counting the rows, try to compare the row values to what the user has input in the username and passoword fields and what is returned from the database rows.
The "hacker" can simply type this and he will be allowed to log in according to the logic of your code:
You just need to retrieve the data stored into dataset variable that you filled using the adapter.
Assuming your database table contains fields like First_Name and 'Last_Name', here is how you can display them on any label control on your form:
adaptor.Fill(dataset, "0")
myFirstName.Text = dataset.Tables(0).Rows(0).Item("First_Name").ToString()
myLastName.Text = dataset.Tables(0).Rows(0).Item("First_Name").ToString()
You can also retrieve the column without having to know its name like this
myLabel.text = = dataset.Tables(0).Rows(0).Item(3).ToString()
'This will retrieve the 4th column from the table (zero based array)
You can also clean up your code by declaring a variable to hold the retrieved table
adaptor.Fill(dataset, "0")
Dim myTable as DataTable = dataset.Tables(0)
myFirstName.Text = myTable.Rows(0).Item(0).ToString()
Hope this helps
I'm trying a new approach for a project that I'm working on and I'm just starting to learn about Access Databases. I using VB.net and my question is: How do you see if a record exists in the table of the database. I thought I had it understood but that is not the case. I'm creating a login and I want it to check if the Username that they typed in exists before it tries to compare what you typed with what's in the database. I see alot of questions on how to do this...but not for VB.net and MS Access
Here's my code:
Imports System.Data.OleDb
Public Class LoginForm1
Dim provider As String
Dim dataFile As String
Dim connString As String
Public myConnection As OleDbConnection = New OleDbConnection
Public dr As OleDbDataReader
Dim Errors As String
Public Sub AccessAccountDatabase()
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\Users\Richard\Documents\Visual Studio 2010\Projects\CybSol Journal Database\CybSol Journal Database\cgi-bin\Data.mdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
Errors = ""
Try
myConnection.Open()
Dim str As String
str = "SELECT * FROM Accounts WHERE Username='" & UsernameTxt.Text & "' AND Password='" & PasswordTxt.Text & "'"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
dr = cmd.ExecuteReader
dr.Read()
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Dim Welcome As String = "SELECT * FROM Accounts WHERE Real_Name=" & "Username"
MsgBox("Welcome back " & dr("Real_Name") & "!")
Else
MsgBox("Login Failure")
End If
myConnection.Close()
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OkayBtn_Click(sender As System.Object, e As System.EventArgs) Handles OkayBtn.Click
AccessAccountDatabase()
End Sub
End Class
So now my question is... How do you get it to check if a record exists in the database, because when you type in the correct information (The correct username and password that exists in the database) it says welcome and all. But when you type in the wrong Username and/or Password it doesn't work. Without the "Try Catch" statement the program just freezes. With the try catch it states this:
System.InvalidOperationException: No data exists for the row/column.
at System.Data.OleDb.OleDbDataReader.DoValueCheck(Int32 ordinal)
at System.Data.OleDb.OleDbDataReader.GetValue(Int32 ordinal)
at System.Data.OleDb.OleDbDataReader.get_Item(String name)
at CybSol_Journal_Database.LoginForm1.AccessAccountDatabase() in c:\users\richard\documents\visual studio 2010\Projects\CybSol Journal Database\CybSol Journal Database\LoginForm1.vb:line 36
Addition information: line 36 is this: If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
First problem:
PASSWORD is a reserved keyword in Access. You should encapsulate in square brackets:
"SELECT * FROM Accounts WHERE Username='" & UsernameTxt.Text & _
"' AND [Password]='" & PasswordTxt.Text & "'"
Second problem:
NEVER use string concatenation to create sql text. ALWAYS use parameters
str = "SELECT * FROM Accounts WHERE Username=? AND [Password]=?"
Dim cmd As OleDbCommand = New OleDbCommand(str, myConnection)
cmd.Parameters.AddWithValue("user", UserNameTxt.Text)
cmd.Parameters.AddWithValue("pass", PasswordTxt.Text)
dr = cmd.ExecuteReader
Why? look here what could happen if you concatenate strings from user input
Third problem: Test if your command returns rows
If dr.Read() Then
......
End if
I added some Using statements so you don't have to manually close the connections. Also, I parameterized the SQL statement to prevent SQL Injection.
Public Class LoginForm1
Dim provider As String
Dim dataFile As String
Dim connString As String
'Public myConnection As OleDbConnection = New OleDbConnection
'Public dr As OleDbDataReader
Dim Errors As String
Public Sub AccessAccountDatabase()
provider = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source ="
dataFile = "C:\Users\Richard\Documents\Visual Studio 2010\Projects\CybSol Journal Database\CybSol Journal Database\cgi-bin\Data.mdb"
connString = provider & dataFile
myConnection.ConnectionString = connString
Errors = ""
Try
Using myConnection As OleDbConnection = New OleDbConnection(connString)
myConnection.Open()
Dim str As String
str = "SELECT * FROM Accounts WHERE Username=#USER AND [Password]=#PWD "
Using cmd As OleDbCommand = New OleDbCommand(str, myConnection)
cmd.Parameters.AddWithValue("#USER", UsernameTxt.Text)
cmd.Parameters.AddWithValue("#PWD", PasswordTxt.Text)
Using dr As OleDbDataReader = cmd.ExecuteReader
If dr.HasRows Then
dr.Read()
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Dim Welcome As String = "SELECT * FROM Accounts WHERE Real_Name=" & "Username"
MsgBox("Welcome back " & dr("Real_Name") & "!")
Else
MsgBox("Login Failure")
End If
Else
MsgBox("Login Failure")
End If
End Using
End Using
End Using
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Private Sub OkayBtn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OkayBtn.Click
AccessAccountDatabase()
End Sub
End Class
You're on the right track. The OleDbDataReader.Read returns a boolean indicating whether or not it successfully read an existing row. Therefore, you can check to see if it returned True before trying to read the record. For instance:
If dr.Read() Then
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Dim Welcome As String = "SELECT * FROM Accounts WHERE Real_Name=" & "Username"
MsgBox("Welcome back " & dr("Real_Name") & "!")
Else
MsgBox("Login Failure")
End If
End If
Also, I feel I should at least mention that storing a password in plain text is never a good idea.
You don't have to check for the username and password in your code again since if does not match in the database, no rows will be returned.
You can simply do
dr = cmd.ExecuteReader
If dr.HasRows Then
//it matched
Else
//it didn't match. could not log in
End If
Your approach is below if you still want to keep it but it's not necessary
dr = cmd.ExecuteReader
If dr.HasRows Then
dr.Read()
If UsernameTxt.Text = dr("Username").ToString AndAlso PasswordTxt.Text = dr("Password").ToString Then
Else
End If
End If
Use the Read() method on your DataReader (note that this keeps your connection to the database open and you'll be unable to execute any other commands on the database while your DataReader is still Reading.
If String.Compare(dr("Username").ToString(), UsernameTxt.Text, true) AndAlso String.Compare(dr("Password").ToString(), PasswordTxt.Text.ToString() Then
' The username and password for the record match
' the input from the login form
ProcessLogin()
Else
' Invalid username or password, send an error
End If