I have a problem with my C# code. I have created a login form in C# 2010. When I am validating the user name, I used an if-condition inside the while loop but the thing is that even when the username and password are correct, it executes the else-statement. Please help me to solve this.
Here is my code :
private void btnlogin_Click(object sender, EventArgs e) {
string connection=
#"Data Source=.\SQLEXPRESS;"
+" AttachDbFilename=|DataDirectory|ResturantDB.mdf;"
+" Integrated Security=True; User Instance=True";
SqlConnection cn=new SqlConnection(connection);
try {
cn.Open();
}
catch(Exception) {
// print the exception's message?
MessageBox.Show("Connection to Database failed; check Connection!");
}
SqlCommand cmd=new SqlCommand("SELECT * FROM [Login]", cn);
cmd.Connection=cn;
SqlDataReader reader=null;
reader=cmd.ExecuteReader();
while(reader.Read()) {
if(
txtuser.Text==(reader["Username"].ToString())
&&
txtpass.Text==(reader["Password"].ToString())
) {
//MessageBox.Show( "logged in!" );
Home newhome=new Home();
newhome.Show();
this.Hide();
}
else {
MessageBox.Show("Incorrect credentials!");
}
}
}
you should use a break, when a username is found in your if condition like
bool found = false;
while (reader.Read())
{
if (txtuser.Text == (reader["Username"].ToString()) && txtpass.Text == (reader["Password"].ToString()))
{
//MessageBox.Show("loged in!");
Home newhome = new Home();
newhome.Show();
this.Hide();
found = true;
break;
}
}
if (!found)
MessageBox.Show("Incorrect credentian..!");
you get into the else block because if any login is not correct, the messagebox appears and that is in n-1 cases in your code.
You're checking if all users have the same user name and password. You need to refine your SQL to select only that one user. Also, please read into password hashing for the sake of your users.
Because its in a loop.
create a bool variable. update its value in loop (if found same username and password) and check outside based on its value.
Do this
bool found;
while (reader.Read())
{
if (txtuser.Text == (reader["Username"].ToString()) &&
txtpass.Text == (reader["Password"].ToString()))
{
found = true;
break;
}
}
if (found)
{
MessageBox.Show("loged in!");
Home newhome = new Home();
newhome.Show();
this.Hide();
}
else
{
MessageBox.Show("Incorrect credentian..!");
}
I will solve it on this way:
private void btnlogin_Click(object sender, EventArgs e)
{
string connection = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|ResturantDB.mdf;Integrated Security=True;User Instance=True";
SqlConnection cn = new SqlConnection(connection);
try
{
cn.Open();
}
catch (Exception)
{
MessageBox.Show("Conncetion to Database faild check Connection !");
}
while (true)
{
SqlCommand cmd = new SqlCommand("SELECT [Password] FROM [Login] WHERE [Username] = '" + txtuser.Text + "'", cn);
cmd.Connection = cn;
SqlDataReader reader = null;
reader = cmd.ExecuteReader();
if (!reader.HasRows)
MessageBox.Show("User does not exist. Please, try again.");
else
{
//username should be unique, so only one row is possible to have
reader.Read();
if (txtpass.Text == (reader["Password"].ToString()))
{
//MessageBox.Show("loged in!");
Home newhome = new Home();
newhome.Show();
this.Hide();
return;
}
else
MessageBox.Show("Incorrect credentian..! Try again.");
}
}
}
Simplest and Secure method
SqlCommand cmd = new SqlCommand("Select uname, pswd from [Login] where uname =#uname and pswd =#ps", conn);
cmd.Parameters.Add(new SqlParameter("#uname", "username here"));
cmd.Parameters.Add(new SqlParameter("#ps", "pasword here"));
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
//MessageBox.Show( "logged in!" );
Home newhome = new Home();
newhome.Show();
this.Hide();
}
else
{
MessageBox.Show( "Incorrect credentials!" );
}
No need to loop thru the records for your case
use this query, compate username and password in the query:
"SELECT * FROM [Login] where Username='" + txtuser.Text "' and password = '" + txtpass.Text + "'"
Related
I am working on a user registration form containing only 3 fields Username,password and confirm password. But when i insert data, if password is mismatching, the exception appears form mismatch but on clicking OK, the data is inserted into db.
what should i do that it only insert on matching password
private void btn_save_Click(object sender, EventArgs e)
{
try
{
conn.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = conn;
string query = "INSERT INTO Users (username,newpassword)values('" + txt_newusr.Text + "','" + txt_password.Text + "')";
if (txt_password.Text == "" || txt_cnfpw.Text == "")
{
MessageBox.Show("Please enter values");
return;
}
if (txt_password.Text != txt_cnfpw.Text)
{
MessageBox.Show("Password confirm password are not matching");
txt_cnfpw.Focus();
}
MessageBox.Show(query);
command.CommandText = query;
command.ExecuteNonQuery();
MessageBox.Show("Record Saved successfully");
conn.Close();
}
}
You should change it like that
if (txt_password.Text == txt_cnfpw.Text)
{
MessageBox.Show(query);
command.CommandText = query;
command.ExecuteNonQuery();
MessageBox.Show("Record Saved successfully");
}
You have to do lots of corrections to make this work properly, Corrections like the following:
Make use of parameterized queries instead for concatenated queries to avoid injection
Process insert only after client-side validations(empty check password match etc)
Make use of using for managing connections and commands
I have added an example below, please have a look
try
{
string query = "INSERT INTO Users (username,newpassword)values(#username,#newpassword)";
bool CanInsertNewUser = true;
if (txt_newusr.Text=="" || txt_password.Text == "" || txt_cnfpw.Text == "")
{
CanInsertNewUser = false;
MessageBox.Show("Please enter values");
}
if (txt_password.Text != txt_cnfpw.Text)
{
CanInsertNewUser = false;
MessageBox.Show("Password confirm password are not matching");
txt_cnfpw.Focus();
}
if (CanInsertNewUser)
{
using (OleDbConnection conn = new OleDbConnection("GiveYourConnectionStringHere"))
{
using (OleDbCommand command = new OleDbCommand())
{
conn.Open();
command.Connection = conn;
command.CommandText = query;
command.Parameters.Add("#username", OleDbType.VarChar).Value = txt_newusr.Text;
command.Parameters.Add("#newpassword", OleDbType.VarChar).Value = txt_password.Text;
command.ExecuteNonQuery();
}
}
MessageBox.Show("Success");
}
}
catch (Exception ex)
{
MessageBox.Show("OLEDB issues : " + ex.Message.ToString());
}
In both the success and failure cases you are attempting to commit the transaction.
Save statements should only be executed if the password is matching. Move the save statements inside the success block as follows.
if (txt_password.Text == txt_cnfpw.Text)
{
MessageBox.Show(query);
command.CommandText = query;
command.ExecuteNonQuery();
MessageBox.Show("Record Saved successfully");
}
else
{
MessageBox.Show("Password confirm password are not matching");
txt_cnfpw.Focus();
}
My problem is I don't know how to call the textboxes and buttons to my class from my form login. So I decided to put my codes inside my btnLogin events. How can I make my codes oop style?
private void btnLogin_Click(object sender, EventArgs e)
{
int count = 0;
Connection connection = new Connection();
string sql = "SELECT * FROM tbl_Account WHERE Username='" + txtUserName.Text + "' and Password='" + txtPassword.Text + "'";
MySqlConnection conn = new MySqlConnection(connection.ConnectionString);
MySqlCommand cmd = new MySqlCommand(sql, conn);
conn.Open();
MySqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
count++;
}
if (count == 1)
{
MessageBox.Show("Login Successfully!");
this.Hide();
main.showMeForm4(this);
}
else
{
txtPassword.Focus();
MessageBox.Show("Username or Password Is Incorrect");
txtUserName.Text = "";
txtPassword.Text = "";
}
conn.Close();
}
Put your business logic to a separate class:
Do not concat SQL query (SQL Injections).
BusinessLogic class
public bool Authorize(string userName, string userPassword)
{
Connection connection = new Connection();
string sql = "SELECT Count(*) FROM tbl_Account WHERE Username=#userName and Password=#userPassword";
MySqlConnection conn = new MySqlConnection(connection.ConnectionString);
MySqlCommand cmd = new MySqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#userName",userName);
cmd.Parameters.AddWithValue("#userPassword",userPassword);
int count = 0;
try
{
conn.Open();
int count = int.TryParse(cmd.ExecuteScalar().ToString());
}
finally
{
con.Close();
}
return count==1;
}
Call it:
BusinessLogic businessLogic = new BusinessLogic();
private void btnLogin_Click(object sender, EventArgs e)
{
if (businessLogic.Authorize(txtUserName.Text, txtPassword.Text)
{
MessageBox.Show("Login Successfully!");
this.Hide();
main.showMeForm4(this);
}
else
{
txtPassword.Focus();
MessageBox.Show("Username or Password Is Incorrect");
txtUserName.Text = "";
txtPassword.Text = "";
}
}
This code is from our user login profile for our SAD project. The account I register for user log in is working since it saved in the database but I can't log in because it says invalid.
private void btn_login_Click(object sender, EventArgs e)
{
conn = new MySqlConnection(myconn);
string query = "select * from southpoint_school.user where userUsername='" + textBox1.Text + "' and userPassword='" + textBox2.Text + "'";
conn.Open();
cmd = new MySqlCommand(query, conn);
MySqlDataReader reader = cmd.ExecuteReader();
int count = 0;
while (reader.Read())
{
count++;
}
if (count == 1)
{
conn = new MySqlConnection(myconn);
string problem = "SELECT userAccountType from southpoint_school.user WHERE userUsername ='" + textBox1.Text + "'";
conn.Open();
cmd = new MySqlCommand(problem, conn);
string answer = cmd.ExecuteScalar().ToString();
conn.Close();
MessageBox.Show("Login successful!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
if (answer == "Administrator")
{
memorable = "Administrator";
frm_main main = new frm_main();
main.Show();
this.Hide();
}
else
{
memorable = "Limited";
frm_main main = new frm_main();
main.Show();
this.Hide();
}
}
else if (textBox1.Text == "" && textBox2.Text == "")
{
MessageBox.Show("No Username and/or Password Found!");
}
else
{
MessageBox.Show("Invalid Username And/Or Password!");
}
conn.Close();
}
The case
Invalid Username And/Or Password!
can only happen when you have 0 ore more than 1 search results in your southpoint_school.user database with your entered username + password. So I would inspect the data in your database.
Additionally I would
use parameters instead of string-concatenation for creating sql statements to avoid injection
save (salted)hashed passwords instead of plaintext in your database
use using statements for more effecient ressurce useage
query the user-table only once and use the result twice
e.g.:
if (string.IsNullOrEmpty(textBox1.Text) || string.IsNullOrEmpty(textBox2.Text))
{
MessageBox.Show("No Username and/or Password Found!");
}
else
{
DataTable dtResult = new DataTable();
string Command = "select * from southpoint_school.user where userUsername=#un and userPassword=#up";
using (MySqlConnection myConnection = new MySqlConnection(ConnectionString))
{
using (MySqlDataAdapter myDataAdapter = new MySqlDataAdapter(Command, myConnection))
{
myDataAdapter.SelectCommand.Parameters.Add(new MySqlParameter("#un", textBox1.Text));
myDataAdapter.SelectCommand.Parameters.Add(new MySqlParameter("#up", textBox2.Text));
myDataAdapter.Fill(dtResult);
}
}
if (dtResult.Rows.Count == 1)
{
MessageBox.Show("Login successful!", "Success!", MessageBoxButtons.OK, MessageBoxIcon.Information);
if ((string)dtResult.Rows[0]["userAccountType"] == "Administrator")
{
memorable = "Administrator";
frm_main main = new frm_main();
main.Show();
this.Hide();
}
else
{
memorable = "Limited";
frm_main main = new frm_main();
main.Show();
this.Hide();
}
}
else if (dtResult.Rows.Count == 0)
{
MessageBox.Show("Invalid Username And/Or Password!");
}
else //TODO: treat the case for multiple results
{
}
}
I have a simple login screen which, upon user clicking login button, should run the sql query to search for rows where the username == username text box, and password == password text box. This section of my code works fine.
However when I try to run an if statement, which will open a new form and close the login form, it errors, even though I have added some message boxes to check that the statement sting comparison is correct.
Any ideas?
Login Button:
private void btnLogin_Click(object sender, EventArgs e)
{
try
{
string connection = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\DebenhamsProjectOfficeDatabase.mdf;Integrated Security=True;User Instance=True";
SqlConnection cn = new SqlConnection(connection);
cn.Open();
string userText = txtUsername.Text;
string passText = txtPassword.Text;
SqlCommand cmd = new SqlCommand("SELECT ISNULL(Username, '') AS Username, ISNULL(Password,'') AS Password FROM Users WHERE Username='" + userText + "' and Password='" + passText + "'", cn);
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
MessageBox.Show(userText + " / " + dr["Username"].ToString());
MessageBox.Show(passText + " / " + dr["Password"].ToString());
if (dr["Username"].ToString() == userText && dr["Password"].ToString() == passText)
{
this.Hide();
Dashboard dashboard = new Dashboard();
dashboard.ShowDialog();
this.Close();
}
else
{
MessageBox.Show("Invalid Username or Password");
}
}
dr.Close();
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Login attempt:
With the advice taken from the Answers and Comments below the code has been corrected to the following (using sql parameters in the sql command):
private void btnLogin_Click(object sender, EventArgs e)
{
try
{
string connection = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\DebenhamsProjectOfficeDatabase.mdf;Integrated Security=True;User Instance=True";
SqlConnection cn = new SqlConnection(connection);
cn.Open();
string userText = txtUsername.Text;
string passText = txtPassword.Text;
SqlCommand cmd = new SqlCommand("SELECT ISNULL(Username, '') AS Username, ISNULL(Password,'') AS Password FROM Users WHERE Username = #username and Password = #password", cn);
cmd.Parameters.Add(new SqlParameter("username", userText));
cmd.Parameters.Add(new SqlParameter("password", passText));
SqlDataReader dr = cmd.ExecuteReader();
try
{
dr.Read();
if (dr["Username"].ToString().Trim() == userText && dr["Password"].ToString().Trim() == passText)
{
this.Hide();
Dashboard dashboard = new Dashboard();
dashboard.ShowDialog();
this.Close();
}
}
catch
{
MessageBox.Show("Invalid Username or Password");
}
dr.Close();
cn.Close();
}
try adding a trim() on to the end of the sql return as you check them.
dr["Username"].ToString().trim() and dr["Password"].ToString().trim()
Sometimes the Database will store extra spaces you cant see.
Simply try this: I think it will work
SqlCommand cmd = new SqlCommand("SELECT * FROM Users WHERE Username='" + userText.toString() + "' and Password='" + passText.toString() + "'", cn);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.Read())
{
MessageBox.Show(username + " / " + usertext);
MessageBox.Show(password + " / " + passtext);
this.Hide();
Dashboard dashboard = new Dashboard();
dashboard.ShowDialog();
this.Close();
}
else
{
MessageBox.Show("Invalid Username or Password");
}
i am trying to make a windows form to log into another one,
i am using a database with users and passwords
the code is as follows:
private void button1_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection("Data Source=mmtsql.XXX.XXXX.XX.XX;Initial Catalog=mmtXX-XXX;User ID=mmtXX-XXX;Password=mmtXX-XXX");
conn.Open();
SqlCommand mycommand = new SqlCommand("SELECT User, Password FROM UsersData WHERE User = '" + textBox1.Text + "' and Password = '" + textBox2.Text + "'", conn);
SqlDataReader reader = mycommand.ExecuteReader();
if(reader != null)
{
if(reader.Read())
{
Form1 formload = new Form1();
formload.Show();
}
else
{
label3.Text = "Invalid Username or Password !";
}
}
else
{
label3.Text = "Invalid Username or Password !";
}
the problem that a getting is that no matter what i insert into the textboxes, right or wrong i am getting:
Invalid Username or Password !
is there anyway to fix my code?
regards;
I would do it this way, keeping to the method you are using:
private void button1_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(conn_str);
conn.Open();
string sql = "SELECT User, Password
FROM UsersData WHERE User=#user and Password=#password"
SqlCommand mycommand = new SqlCommand(sql, conn);
//parameterize your query!
mycommand.Parameters.AddWithValue("user", txtuser.text);
mycommand.Parameters.AddWithValuye("password", txtpassword.password);
SqlDataReader reader = mycommand.ExecuteReader();
if(reader == null)
{
label3.Text = "Database query failed!";
}
else if(reader.HasRows)
{
Form1 formload = new Form1();
formload.Show();
}
else
{
label3.Text = "Invalid Username or Password !";
}
Use parameterized queries as they will help you against sql injection as mentioned by SLaks.
Change your code to below
using (SqlCommand command = new SqlCommand("SELECT User, Password
FROM UsersData WHERE User=#user and Password=#password", connection))
{
//
// Add new SqlParameter to the command.
//
command.Parameters.Add(new SqlParameter("user ", textbox1.text));
command.Parameters.Add(new SqlParameter("password", textbox2.text));
SqlDataReader reader = command.ExecuteReader();
if (reader == null)
{
Form1 formload = new Form1();
formload.Show();
}
else
{
label3.Text = "Invalid Username or Password !";
}
}