I want to create a Registration and Log In form on Visual Studio 2010 (with Visual C#).
I have created Service-Based Database and one table. I can insert data into the table (at the registration form), but I cannot figure out how to log in the user.
I have a very simple Log In Form (just fields for username and password) and a 'Log In' Button. I do not really know how to check if the password and the username (that exist in my database) match. Here is what I have so far:
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text != "" & textBox2.Text != "")
{
cn.Open(); // cn is the Sqlconnection
cmd.Parameters.AddWithValue("#Username", textBox1.Text); // cmd is SqlCommand
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
if (cmd.CommandText == "SELECT * FROM Table1 WHERE username = #Username AND password = #Password")
{
MessageBox.Show("Loggen In!");
this.Close();
}
cn.Close();
}
}
You need to Execute the query to know if the information exists in the database
if (textBox1.Text != "" & textBox2.Text != "")
{
string queryText = #"SELECT Count(*) FROM Table1
WHERE username = #Username AND password = #Password";
using(SqlConnection cn = new SqlConnection("your_connection_string"))
using(SqlCommand cmd = new SqlCommand(queryText, cn))
{
cn.Open();
cmd.Parameters.AddWithValue("#Username", textBox1.Text);
cmd.Parameters.AddWithValue("#Password", textBox2.Text);
int result = (int)cmd.ExecuteScalar();
if (result > 0)
MessageBox.Show("Loggen In!");
else
MessageBox.Show("User Not Found!");
}
}
I have also changed something in your code.
Changed the query text to return just the count of the users with the
specific username and account and be able to use ExecuteScalar
Enclosed the creation of the SqlConnection and SqlCommand in a using
statement to be sure to dispose these objects at the end of the
operation
I also recommend to change the the way in which you store the password.
Store, in the password field, an hash not the clear password. Then pass to the database the same hash and compare this against the content of the database field.
In this way, the password is known only to your user, not by you or by any passersby that looks at the database table
SqlConnection con = new SqlConnection("connection_string");
SqlCommand cmd = new SqlCommand("select Count(*) from [dbo].[Table] where uname=#uname and password=#password");
cmd.Connection = con;
con.Open();
cmd.Parameters.AddWithValue("#uname", uname.Text);
cmd.Parameters.AddWithValue("#password", password.Text);
int Result=(int)cmd.ExecuteScalar();
if (Result > 0)
{
Response.Redirect("welcome.aspx");
}
else
{
Response.Redirect("register.aspx");
}
Related
Pro devs, I have a problem with my code in c#.net and I knew you can help me. the problem is in the Login code, every time I entered a value that is existed in the database it says "Username or password is incorrect" and when I entered a value that does not exist in the DB it says again "Username or password is incorrect" please help me thank you.
I have tried to edit the query and remove the open close in the asterisk but the output is the same.
public void checkLoginAccount()
{
frmMain frmLogin = new frmMain();
con = new MySqlConnection();
con.ConnectionString = "server=localhost;userid=root;password=alpine;port=3305;database=pos_db;pooling=false;SslMode=none";
con.Open();
string qry = "SELECT COUNT(*) FROM pos_db.tbllogin WHERE BINARY Username=#user AND BINARY Password=#pass";
MySqlCommand cmd = new MySqlCommand(qry, con);
cmd.Parameters.AddWithValue("#user", frmLogin.txtUsername.Text);
cmd.Parameters.AddWithValue("#pass", frmLogin.txtPassword.Text);
int count = Convert.ToInt32(cmd.ExecuteScalar());
if (count != 0)
{
MessageBox.Show("Welcome");
}
else
{
MessageBox.Show("Either username or password is incorrect!");
return;
}
con.Close();
con.Dispose();
}
You are creating a new form instance in your function:
frmMain frmLogin = new frmMain();
So the username and password are always empty here:
cmd.Parameters.AddWithValue("#user", frmLogin.txtUsername.Text);
cmd.Parameters.AddWithValue("#pass", frmLogin.txtPassword.Text);
You need to use the right instance of your form.
Try reading the rows and count in the code. That should look something like this:
string qry = "SELECT Username FROM pos_db.tbllogin WHERE BINARY Username=#user AND BINARY Password=#pass";
MySqlCommand cmd = new MySqlCommand(qry, con);
cmd.Parameters.AddWithValue("#user", frmLogin.txtUsername.Text);
cmd.Parameters.AddWithValue("#pass", frmLogin.txtPassword.Text);
mySqlDataReader reader = cmd.ExecuteReader();
if(reader.Read() == true)
{
MessageBox.Show("Welcome");
}
else
{
MessageBox.Show("Either username or password is incorrect!");
return;
}
I have to make a simple login that will not crash when you insert into the browser a (") so i needed to parameterize the query string but for some reason im gettin an error saying:
Must declare the scalar variable "#UserName"
here is the code
private void DoSqlQuery()
{
try
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RolaConnectionString"].ConnectionString);
conn.Open();
string checkUser = "select * from UserData where UserName = #UserName";
SqlCommand com = new SqlCommand(checkUser, conn);
com.Parameters.AddWithValue("#Username", txtUserName.Text.Trim());
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPassword = "select Password from UserData where UserName = #UserName";
SqlCommand passConn = new SqlCommand(checkPassword, conn);
com.Parameters.AddWithValue("#Username", txtUserName.Text.Trim());
string password = passConn.ExecuteScalar().ToString();
conn.Close();
if (password == txtPassword.Text)
{
Session["New"] = txtUserName.Text;
Response.Write("Password is correct");
Response.Redirect("~/LoggedIn.aspx");
}
else
{
Response.Write("Password is not correct");
}
}
else
{
Response.Write("Username is not correct");
}
}
catch(Exception e)
{
Response.Write(e.ToString());
}
}
You are referencing the wrong command in the inner if statement:
string checkPassword = "select Password from UserData where UserName = #UserName";
SqlCommand passConn = new SqlCommand(checkPassword, conn);
com.Parameters.AddWithValue("#Username", txtUserName.Text.Trim());
^^^-- should be passConn
As a result, your second command never gets the parameter added so you get the error you mention. Case sensitivity may also be a problem, but it depends on the collation of your database - SQL Server is case-insensitive by default.
Some other suggestions not related to your problem:
Wrap commands and connection in using statements
Query the username and password in one query (WHERE UserName = #UserName AND Password = #Password). Hackers will first search for valid usernames, then try to hack the password using dictionary attacks. Trying to find a matching combination is much harder.
Do not store your passwords in plain text - use a salted hash
Or just use built-in security providers rather than rolling your own.
I've written this registration form which adds data to my SQL Server database. What I want is an exception when the user enters a username that is already in the database.
protected void Button1_Click(object sender, EventArgs e)
{
try
{
SqlConnection conn2 = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn2.Open();
string CheckUser = "select Username from UserData where Username like #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn2);
com2.Parameters.AddWithValue("#Username", "'%"+ UsernameTextBox.Text +"%'");
com2.ExecuteNonQuery();
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
conn2.Close();
if (IsMatch == 0)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString);
conn.Open();
string InsertQuery = "insert into UserData (Username, Email, Password, Country) values (#Username, #Email, #Password, #Country)";
SqlCommand com = new SqlCommand(InsertQuery, conn);
com.Parameters.AddWithValue("#Username", UsernameTextBox.Text);
com.Parameters.AddWithValue("#Email", EmailTextBox.Text);
com.Parameters.AddWithValue("#Password", PasswordTextBox.Text);
com.Parameters.AddWithValue("#Country", CountryDropDownList.SelectedItem.ToString());
com.ExecuteNonQuery();
Response.Redirect("Manager.aspx");
conn.Close();
}
else
{
Response.Write("User Already Exists!");
}
}
catch (Exception ex)
{
Response.Write(Convert.ToString(ex));
}
}
When I run it, I get an exception on the following line:
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
Blam's second solution works, but the IsMatch can be simplified a bit by casting to int instead of going to string and parsing.
This should also be handled at the database level. Set a primary key on your username column:
ALTER TABLE UserData ADD CONSTRAINT
PK_UserData PRIMARY KEY CLUSTERED (Username)
If you do it this way, then you don't even have to check for duplicates explicitly, you can just try to create the user and handle the exception if it fails:
try
{
using (var conn = new SqlConnection((ConfigurationManager.ConnectionStrings["RegistrationConnectionString"].ConnectionString)))
{
conn.Open();
#if DOUBLE_CHECK
string CheckUser = "select count(*) from UserData where Username = #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn);
com2.Parameters.AddWithValue("#Username", UsernameTextBox.Text);
if ((int)com2.ExecuteScalar() > 0)
{
Response.Write("User already exists");
return;
}
#endif
string InsertQuerry = "insert into UserData (Username,Email,Password,Country) values (#Username,#Email,#Password,#Country)";
SqlCommand com = new SqlCommand(InsertQuerry, conn);
com.Parameters.AddWithValue("#Username", UsernameTextBox.Text);
com.Parameters.AddWithValue("#Email", EmailTextBox.Text);
com.Parameters.AddWithValue("#Password", PasswordTextBox.Text);
com.Parameters.AddWithValue("#Country", CountryDropDownList.SelectedItem.ToString());
com.ExecuteNonQuery();
Response.Redirect("Manager.aspx");
}
}
catch (SqlException se)
{
if (se.Errors.OfType<SqlError>().Any(e => e.Number == 2627))
{
Response.Write("User already exists");
}
else
{
Response.Write(se.ToString());
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
If you handle the exception this way, the #if DOUBLE_CHECK section is redundant and can be removed. An attempt to add duplicate name will cause a SQL error and exception, and this will detect and handle the "duplicate key" error.
Two unrelated notes on your code:
Response.Redirect() will abort the current thread and your conn.Close() will not be called. Use a using() to ensure it's called.
Storing a password in the database as plain text is a disaster waiting to happen. PLEASE take a look at Best way to store password in database for some ideas about how to do this correctly
That won't return an integer
string CheckUser = "select count(*) from UserData where Username like #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn2);
com2.Parameters.AddWithValue("#Username", "'%"+ UsernameTextBox.Text +"%'");
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
And you don't need to use two different connections.
Just use one and close it in a Finally.
string CheckUser = "select count(*) from UserData where Username = #Username";
SqlCommand com2 = new SqlCommand(CheckUser, conn2);
com2.Parameters.AddWithValue("#Username", UsernameTextBox.Text );
int IsMatch = Convert.ToInt32(com2.ExecuteScalar().ToString());
This returns 0 or 1. This should fix your issue. Looks like you need to return an int type. Or you could change it to bool if you want. Either way, this sql statement should help! :)
select
isnull(convert(bit,(select top 1 case
when username != '' then 1
else 0 end
from UserData
where username like #Username)),0)
try
{
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source= C:\Users\jay.desai\Documents\Visual Studio 2008\Projects\Jahoo Sign in form!\Jahoo Sign in form!\Registration_form.mdb");
con.Open();
OleDbCommand cmd = new OleDbCommand("select * from Login where Username='"+txtlognUsrnm.Text+"' and Password='"+txtlognpswrd+"'", con);
OleDbDataReader dr = cmd.ExecuteReader();
if(dr.Read() == true)
{
MessageBox.Show("Login Successful");
}
else
{
MessageBox.Show("Invalid Credentials, Please Re-Enter");
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
I have created one login form and one table in microsoft access which contains username and password fields.when i click on login button it always shows else message though the username and password is same as in table.
The word PASSWORD is a reserved keyword in access-jet. You need to encapsulate it in square brackets.
OleDbCommand cmd = new OleDbCommand("select * from Login where Username=" +
"? and [Password]=?", con);
Also do not use string concatenation to build sql commands but a parameterized query
There are other problems in your code above.
First try to use the using statement to be sure that the connection and other disposable objects are correctly closed and disposed.
Second, if you need only to check the login credentials, then there is no need to get back the Whole record and you could use the ExecuteScalar method avoiding the OleDbDataReader object
string constring = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source= C:\Users\jay.desai\Documents\Visual Studio 2008\Projects\Jahoo Sign in form!\Jahoo Sign in form!\Registration_form.mdb";
string cmdText = "select Count(*) from Login where Username=? and [Password]=?"
using(OleDbConnection con = new OleDbConnection(constring))
using(OleDbCommand cmd = new OleDbCommand(cmdText, con))
{
con.Open();
cmd.Parameters.AddWithValue("#p1", txtlognUsrnm.Text);
cmd.Parameters.AddWithValue("#p2", txtlognpswrd.Text); // <- is this a variable or a textbox?
int result = (int)cmd.ExecuteScalar()
if(result > 0)
MessageBox.Show("Login Successful");
else
MessageBox.Show("Invalid Credentials, Please Re-Enter");
}
How do I fix the IF statement so when the user tries to sign up using an already existing username. Currently my program will not accept the data entered if the username is already existing, but it still proceeds to the next page (even though the data is not saved in the database). What I need to know is how to eliminate the problem so when the user does enter a "username" that exists it'll just give the message box for the error and not move to the next page.
Thanks!
private void btnSignupNew_Click(object sender, EventArgs e)
{
if (txtUsername.Text == "")
{
errorUsername.SetError(txtUsername, "Enter A Username");
}
else if (txtPassword.Text == "")
{
errorPassword.SetError(txtPassword, "Enter A Valid Password");
}
else
{
using (SqlConnection con = new SqlConnection("Data Source=etc"))
{
con.Open();
bool exists = false;
// create a command to check if the username exists
using (SqlCommand cmd = new SqlCommand("select count(*) from [User] where UserName = #UserName", con))
{
cmd.Parameters.AddWithValue("UserName", txtUsername.Text);
exists = (int)cmd.ExecuteScalar() > 0;
}
// if exists, show a message error
if (exists)
{
MessageBox.Show("Username: " + txtUsername.Text + " already Exists");
//errorPassword.SetError(txtUsername, "This username has been using by another user.");
}
else
{
// does not exists, so, persist the user
using (SqlCommand cmd = new SqlCommand("INSERT INTO [User] values (#Forename, #Surname, #Username, #Password)", con))
{
cmd.Parameters.AddWithValue("Forename", txtForename.Text);
cmd.Parameters.AddWithValue("Surname", txtSurname.Text);
cmd.Parameters.AddWithValue("UserName", txtUsername.Text);
cmd.Parameters.AddWithValue("Password", txtPassword.Text);
cmd.ExecuteNonQuery();
}
}
con.Close();
MessageBox.Show("Sucessfully Signed Up");
Form1 signin = new Form1();
signin.Show();
this.Close();
}
}
}
}
Your code is always going to close the form and launch the login form, regardless of whether the username already existed or not, because the logic to do the login form is executed after your test for uniqueness. It should only happen when the test for uniqueness suceeds.
Change your logic to look like this:
// if exists, show a message error
if (exists)
{
MessageBox.Show("Username: " + txtUsername.Text + " already Exists");
//errorPassword.SetError(txtUsername, "This username has been using by another user.");
}
else
{
// does not exists, so, persist the user
using (SqlCommand cmd = new SqlCommand("INSERT INTO [User] values (#Forename, #Surname, #Username, #Password)", con))
{
cmd.Parameters.AddWithValue("#Forename", txtForename.Text);
cmd.Parameters.AddWithValue("#Surname", txtSurname.Text);
cmd.Parameters.AddWithValue("#UserName", txtUsername.Text);
cmd.Parameters.AddWithValue("#Password", txtPassword.Text);
cmd.ExecuteNonQuery();
}
MessageBox.Show("Sucessfully Signed Up");
Form1 signin = new Form1();
signin.Show();
this.Close();
}
con.Close();
Change your Parameters to look like the following as well
I would also recommend adding some sort of Validation if necessary to the edit boxes in case someone adds improper values to prevent from any SQL Injectection personally I would create Property values for the Edit boxes and pass in the Property Value(s). just a suggestion
First problem in your code that stood out to me was the following line
cmd.Parameters.AddWithValue("UserName", txtUsername.Text);
should be
cmd.Parameters.AddWithValue("#UserName", txtUsername.Text);
// if exists, show a message error
if (exists)
{
MessageBox.Show("Username: " + txtUsername.Text + " already Exists");
//errorPassword.SetError(txtUsername, "This username has been using by another user.");
}
else
{
// does not exists, so, persist the user
using (SqlCommand cmd = new SqlCommand("INSERT INTO [User] values (#Forename, #Surname, #Username, #Password)", con))
{
cmd.Parameters.AddWithValue("#Forename", txtForename.Text);
cmd.Parameters.AddWithValue("#Surname", txtSurname.Text);
cmd.Parameters.AddWithValue("#UserName", txtUsername.Text);
cmd.Parameters.AddWithValue("#Password", txtPassword.Text);
cmd.ExecuteNonQuery();
}
MessageBox.Show("Sucessfully Signed Up");
Form1 signin = new Form1();
signin.Show();
this.Close();
}
con.Close();