Hi guys can somebody instruct me on how to solve this problem. I am connecting to a database in the bin debug file whilst using SQLite. I want to check if the login details of the user are correct and when the code verifies that the login details are correct I want to check if the person has registered as a administrator or in this case lecturer however when I don't know how to pull the data from the specific user that has logged in to check if they are a lecturer. There is my code:
string Query = string.Format("SELECT [username], [password], [isLecturer] FROM users");
SQLiteConnection DataBaseConnection = new SQLiteConnection(ConnectionString);
SQLiteCommand Command = new SQLiteCommand(Query, DataBaseConnection);
DataBaseConnection.Open();
using (var reader = Command.ExecuteReader())
{
while (reader.Read())
{
if ((reader.GetString(0) == txtUsername.Text) && (reader.GetString(1) == txtpassword.Text))
{
string Query2 = string.Format("SELECT [isLecturer] FROM users WHERE ");
if ((reader.GetString(2) == "1"))
{
this.Hide();
FetchingTheMainConwaysForm(1);
}
else if ((reader.GetString(2) == "0"))
{
this.Hide();
FetchingTheMainConwaysForm(0);
}
break;
}
else
{
MessageBox.Show("Username or password incorrect", "Authentication Problem", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
DataBaseConnection.Close();
You are selecting whole table in the code. This will make your app slow. I will suggest to send user name and password to the database like below
SELECT [username], [password], [isLecturer] FROM users WHERE [username]=txtUsername.Text AND [password]=txtpassword.Text
If this query returns a row this means it is a successful login otherwise show error message to user.
Now, for successful login use that selected columns through out the code.
My suggestion, Don't use column like [isLecturer]. Make it Role and add values like administrator, lecturer, student etc. (Standard way is to create one more table with RoleId and Role, and use that RoleId in your main table) So in future you can add more roles without doing any more changes in code. You can easily compare user role and give privileges/features depending on role.
And add trim and more validations.
Related
I am developing a login system using ASP.NET 7.0. I have created the login and signup system, by connecting to an SQL database and inserting or querying it for information. Currently, the backend code is able to create accounts, and check to make sure that while making an account, that their is no user with matching email or username. I would like to be able to display some sort of message saying "An account with those details has already been created, Login?". How would I go about this?
Here is my current code:
public void OnPostSignup()
{
System.Diagnostics.Debug.WriteLine("Post Request Received");
// Creating Credentials //
string InputUser = Request.Form["signup-user"];
string InputPassword = Request.Form["signup-pwd"];
string InputEmail = Request.Form["signup-email"];
// Creates a new SQL Connection using the connection string provided - Then runs an SQL Command: NOTHING HAS BEEN RUN YET, ONLY INSTANCIATED //
using (SqlConnection conn = new SqlConnection("Valid Server String Here"))
using (SqlCommand cmd = new SqlCommand("INSERT INTO AccountData ([User], [Password], [Email]) VALUES (#1, #2, #3);", conn))
{
// The Placeholder Values are replaced with the string variables created above containing our account registration data //
cmd.Parameters.AddWithValue("#1", InputUser);
cmd.Parameters.AddWithValue("#2", InputPassword);
cmd.Parameters.AddWithValue("#3", InputEmail);
// Instanciates a new SQL Command that will cehck the database to ensure an account with that infomation hasnt been created already //
using (SqlCommand UserCheck = new SqlCommand("SELECT * FROM AccountData WHERE [User] = #1 AND [Email] = #2", conn))
{
// Adds the inputted data into the UserCheck SQL Command //
UserCheck.Parameters.AddWithValue("#1", InputUser);
UserCheck.Parameters.AddWithValue("#2", InputEmail);
// A connection to our SQL Databasse is opened //
conn.Open();
// Executes a data reader on our SQL Server
SqlDataReader reader= UserCheck.ExecuteReader();
// This logic gate checks if the reader returns any rows with the given infomation - if yes, no account is created, and the connection is closed - if no, the account creation is started //
if(reader.HasRows)
{
// We already have an account with the same email or username //
reader.Close();
conn.Close();
// Display some sort of message to the user saying that their email or username is already in use. //
}
else
{
// We do not have an account with that information - An account can now be created //
// Closes the reader, because we cannot query our SQL databse twice at the same time //
reader.Close();
// Executes the 'cmd' SQL command against our SQL Databse //
cmd.ExecuteNonQuery();
// Closes the connection to our SQL Databse for security - and cost //
conn.Close();
}
}
}
}
// This will run when the user clicks the "Login button, after filling out all the required fourm felids //
public void OnPostLogin()
{
// Takes the data inputted by the user, and stores them as variables to be ran against the SQL Database //
string LoginUser = Request.Form["login-user"];
string LoginPass = Request.Form["login-passwrd"];
// Defines an SQL Connection with our SQL Connection String //
using (SqlConnection conn = new SqlConnection("Valid Connection String Here"))
// Creates a new SQL command that checks the database for a account; notice that '#1' amd '#2' are placeholders //
using (SqlCommand cmd = new SqlCommand("SELECT * FROM AccountData WHERE [User] = #1 AND [Password] = #2", conn))
{
// Replaces the placeholder values in the SQL command with our varaibles that were created from the users input
cmd.Parameters.AddWithValue("#1", LoginUser);
cmd.Parameters.AddWithValue("#2", LoginPass);
// A connection is opened to our SQL Database //
conn.Open();
// Executes the SQL Database reader with the paramaters defined in our SQL Command 'cmd' //
SqlDataReader reader = cmd.ExecuteReader();
// Checks if the SQL reader returned any rows //
if (reader.HasRows)
{
// User Exists //
reader.Close();
System.Diagnostics.Debug.WriteLine("We have found an account");
// Log in the user //
}
else
{
// User Doesnt Exist //
reader.Close();
System.Diagnostics.Debug.WriteLine("No Account Found");
}
// Closes the connection to our SQL Database //
conn.Close();
}
}
I am aware that the code may be vunrable to SQL injection attacks! the website has not been published yet, and security will be added before launch.
I appreciate any help that I receive, if there is anything that doesn't make sense, please let me know!
Thanks for the help everybody! However, i have found a solution to the problem. Inside of the if statement where login details are verified, i added this onto the 'invalid login' return.
ModelState.AddModelError("InvalidLogin", "Invalid login details");
And then, directly below my login form i added the following code
#if (Model.ModelState.ContainsKey("InvalidLogin"))
{
<div class="alert alert-danger">#Model.ModelState["InvalidLogin"].Errors[0].ErrorMessage</div>
System.Diagnostics.Debug.WriteLine("Error message displayed in view");
}
else
{
System.Diagnostics.Debug.WriteLine("No error message to display in view");
}
If you are viewing this post late, looking for an answer, this worked well for me. If you would like help setting this up for your code feel free to # me
I want to make a registration and login system. It is possible to register, the user information is saved in the sql table, but if the user wants to log in, the user in the 0th index in the sql table seems to be logged in. I tried to bring the user information on the main screen with conditional sql commands, but for example, if I check the phone number and get the information, it still gets the phone number in the 0th index.
//this is the code i am trying to get username to label
MainMenu mainMenu = new MainMenu();
if (connection.State == ConnectionState.Closed)
{
connection.Open();
}
command.Connection = connection;
command.CommandText = "select First_Name from ACCOUNTS where Phone_Number=#Phone_Number";
command.Parameters.Add("#Phone_Number", PhoneNmb.Text);
string ClientName= (string)command.ExecuteScalar();
//PhoneNmb.Text is login screens textbox.text
label.Text = "Hoşgeldiniz " + ClientName;
if (connection.State == ConnectionState.Open)
{
connection.Close();
}
Accounts table data:
Accounts table view designer (ID SPECİFİCATİONS TRUE):
I am trying to create a MyAccount page for a website I am making using ASP.NET and Bootstrap with html and C# running in the background for our objects. We are using SQL Server to run our databases and I am having a LOT of troubles getting my updates to go through. I am using a test user profile I had my partner hard insert into the system as I have not programmed the account creation system yet, only the login.
The issue is that when I run my update code the SQL Server database does not update with the passed information. I receive no exceptions and I know my connection string works as I use it to log in and drag contents of my database into text boxes on the main screen. Because of this I have no idea why it is not updating and I feel very lost.
I have removed bits of the connection string itself as this server is not my own and I don't want my professor's personal connection and login credentials being on the internet.
My debug label running a query tells me each time I attempt to change the state variable on the item that 1 row was effected.
The user profile I am trying to update has the following information stored in it.
Username: MarshallE
Email: Test1234
Password: Test1234!
First Name: Marshall
Last Name: Emmer
Properties Rented: Prime Place
Universities Attended Oklahoma State University
State: N/A (My partner just added this and didn't update the profile)
Here is my code I used to try and update the thing:
protected void btnRegAcctUpdate_Click(object sender, EventArgs e)
{
// This unit's job is to update the database of the specified user with the info in the text boxes
// Make sure the password fields are the same
if (txtAcctPass1.Text == txtAcctPass2.Text)
{
lblAcctDebug.Text = "";
SqlConnection MyConnection = new SqlConnection();
MyConnection.ConnectionString = "Server= (N/A ;Database=F19_groupRoss;User Id=groupRoss;Password = (N/A);";
string MyUpdateStatement;
MyUpdateStatement = "UPDATE dbo.UserID SET Email = #Email, Password = #Password, FirstName = #FirstName, LastName = #LastName, Universities = #University, Town = #Town, State = #State" + " WHERE UserID = #UserID";
SqlCommand MySqlCmd = new SqlCommand(MyUpdateStatement, MyConnection);
// These are the values we will be overriding the database with
MySqlCmd.Parameters.AddWithValue("#UserID", (string)Session["UserID"]);
MySqlCmd.Parameters.AddWithValue("#FirstName", txtAcctFirstName.Text);
MySqlCmd.Parameters.AddWithValue("#LastName", txtAcctLastName.Text);
MySqlCmd.Parameters.AddWithValue("#Email", txtAcctEmail.Text);
MySqlCmd.Parameters.AddWithValue("#Password", txtAcctPass1.Text);
MySqlCmd.Parameters.AddWithValue("#State", txtAcctState.Text);
MySqlCmd.Parameters.AddWithValue("#Town", txtAcctTown.Text);
MySqlCmd.Parameters.AddWithValue("#University", txtAcctUniversity.Text);
// Open the connection
MyConnection.Open();
int rows = MySqlCmd.ExecuteNonQuery();
lblDebug2.Text = "Rows affected: " + rows;
MyConnection.Close();
}
else
{
lblAcctDebug.Text = "Error: Please ensure the text in the new password and password confirmation boxes are identical";
}
}
If anyone can tell me what I am doing wrong I would REALLY appreciate it!
Try adding your parameters like this:
MysqlCmd.Parameters.Add(New Parameter(#FirstName, txtAcctFirstName.text));
I want to build a simple loop to check incoming data from SQL server, compare it to a textfield, and execute non query if there are no duplicates.
I wrote this code:
try
{
bool exists = false;
conn = new SqlConnection(DBConnectionString);
SqlCommand check_user = new SqlCommand("SELECT usrEmail FROM tblUsers", conn);
SqlCommand add_user = new SqlCommand("INSERT INTO tblUsers (usrEmail, usrPassword, usrRealname, usrIsowner) VALUES (#email, #pass, #name, #owner)", conn);
// (I have removed all the paramaters from this code as they are working and irrelevant)
conn.Open();
SqlDataReader check = check_user.ExecuteReader();
while (check.Read())
{
if (Convert.ToString(check[0]) == UserEmail.Text)
{
MessageBox.Show("The email you entered already exists in the system.");
exists = true;
break;
}
}
if (exists == false)
{
add_user.ExecuteNonQuery();
}
else
{
return;
}
}
catch (Exception ex)
{
MessageBox.Show("There was a problem uploading data to the database. Please review the seller's details and try again. " + ex.Message);
return;
}
finally
{
conn.Close();
}
I used breakpoints and saw that the code runs the while loop fine, but when it reaches the ExecuteNonQuery command, it returns an error message:
there is already an open datareader associated with this command which
must be closed first
I tried to use a check.Close(); command, but when I do, it suddenly gets stuck with the duplicate email error message for reasons passing understanding.
Additionally, there was a fix I tried in which the data actually WAS sent to the database (I saw it in SQL Server Management Studio), but still gave an error message... That was even stranger, since the nonquery command is the LAST in this function. If it worked, why did it go to the catch?
I have searched the site for answers, but the most common answers are MARS (I have no idea what that is) or a dataset, which I do not want to use in this case.
Is there a simple solution here? Did I miss something in the code?
The simples way out would be:
using(SqlDataReader check = check_user.ExecuteReader())
{
while (check.Read())
{
if (Convert.ToString(check[0]) == UserEmail.Text)
{
MessageBox.Show("The email you entered already exists in the system.");
exists = true;
break;
}
}
}
That said, there are some serious problems with this code.
First of all, you don't really want to read all users just to check that an email address is already taken. select count(*) from tblUsers where usrEmail = #email is fine...
...or not, because there's a possibility of a race condition. What you should do is add a unique constraint on a usrEmail column and just insert into tblUsers, catching violations. Or you can use merge if you feel like it.
Next, you don't really want to have your data access code all over the place. Factor it out into separate classes/methods at least.
I just finished a database in C# with SQL. In my database I add data when I create the account for a person. I add the username, password, first and last name and the type (client or administrator).
When I am logging in all what I do is to check if username and password are correct. Here is the code.
private void button1_Click(object sender, EventArgs e)
{
con = new SqlConnection(#"Data Source=MARIA-PC;Initial Catalog=Account;Integrated Security=True");
SqlCommand cmd1 = new SqlCommand("SELECT * FROM [dbo].[Cont] WHERE Username = #Username and Password = #Password;", con);
cmd1.Parameters.AddWithValue("#Username", this.Username.Text);
cmd1.Parameters.AddWithValue("#Password", this.Password.Text);
cmd1.Connection = con;
con.Open();
DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter(cmd1);
da.Fill(ds);
con.Close();
bool loginSuccessful = ((ds.Tables.Count > 0) && (ds.Tables[0].Rows.Count > 0));
if (loginSuccessful )
{
MessageBox.Show("You logged in successfully!","Success!");
this.Visible = false;
f3.ShowDialog();
this.Visible = true;
}
else
{
MessageBox.Show("Invalid username or password!", "Error!");
}
}
And next what I want to do is to check if for this username and password the type is for client or administrator. And if is for administrator to entry in a form or if is for client to entry in another form.
How can I do? I need some ideas.
Here is the table:
You are retrieving the full row from your database table, so you have also retrieved the column that contains the usertype. You just need to check it after verifying the login
Here an example assuming that a "1" value means administrator, a "2" means normal user (of course you could change these constants to your actual values)
if (loginSuccessful )
{
string userType = ds.Tables[0].Rows[0]["Type"].ToString();
if(userType == "1")
{
// User is an administrator, go to admin form
}
else if(userType == "2")
{
// User is a normal user, go to user form
}
else
{
// Unexpected value, error message?
}
}
A side note, while you are using parameters there is still a security problem in your database/code logic. It seems that you store your password as a plain text. This could give to anyone that looks at your database table the possibility to know your users passwords. A password should never be stored in plain text. This site contains a lot of answer on how to correctly store passwords in a database
Start from here:
Best way to store passwords in a database