• (3 Pages)
  • +
  • 1
  • 2
  • 3

C# Login/Register system using SQL Compact

#1 optix212  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 27
  • View blog
  • Posts: 509
  • Joined: 10-October 09

Posted 22 April 2013 - 04:44 PM

C# Register/Login system using SQL Compact
Written by Brandon Miller

Introduction

Hello all, I am here today to show you how to create a Register/Login system that you could use with any program that you choose. I will teach you how to create an SQL Compact Database, how to create a TabControl and use it efficiently, and most of all, how to code your very own login/register system that even sends a thank you email! You should be able to follow this tutorial even if you are a beginner, but please, if you have any questions at all, I really encourage you to ask them. If you feel uncomfortable asking them on the forums, please ask me in a PM. Remember, I AM HERE TO HELP. That is why I am making these tutorials. I will be updating my tutorial series pretty regularly, so please make sure to check back. Also, if you have any tutorial ideas please feel free to ask, because I seriously enjoy making them.

What you should know:
• What a variable is
• How to make a new WinForms project
• What an array is
• How to drag/drop tools from the toolbox.

What you will learn:
• How to create a SQL Server Compact edition database within the Visual Studio IDE.
• How to create a DataGridView with bound data to it.
• How to add Tables to a database, and columns to that table.
• How to programmatically add data to your table.
• How to send programmatically send emails.
• How to encode passwords for storage in databases.


Contents:
1. Setting up your Form
2. Creating a SQL Server Compact Database
3. Adding functionality to the form

Setting up your Form

The first thing we need to do is create a new WinForms application and name it LoginSystem. Click on the toolbox and drag a TabControl onto your form. Change the TabControls “Dock” property to Fill. This will fill up your form with the TabControl. Now, click on the “…” button on the TabPages property to bring up a new window showing the details of all of the tabs. Change tabPage1’s Text property to “Login”, and tabPage2’s Text property to “Register”. Next, click the Add button to add a new tabPage, and change it’s Text property to “Database”. Create one more tabPage, and change its text property to “Configuration”. I will explain more about the database tab later.

Login Tab:
With the login tab clicked, drag two Labels, two textboxes, and one button to the form. Set one labels text property to “Username: “, and drag a corresponding textbox beside it. Change the name property of its corresponding textbox to “loginUserName”. Next, change the second labels text property to “Password: “, and drag a corresponding textbox next to it. Change the name of the textbox to “loginPassword” and change its PasswordChar property to “*”. Finally, change the Text property of the button to “Login”, and the Name property of the button to “loginButton”.

Register Tab:
Make sure you have the Register tab clicked, and make 4 labels, 4 textboxes to go with them, and one button. Change the first labels text property to “Username: “, change the second labels text property to “Password: “, the third labels text property to “Confirm: “, and the fourths to “Email: “. Drag the textboxes to where they are aligned side by side with the labels, and click on the textbox next to the username label and change its Name property to “registerUserName”. Next, click the textbox next to the password label and change its Name property to “registerPassword”, also change its PasswordChar property to “*”. The third textbox’s name should be aligned next to the Confirm label, its name should be changed to “registerConfirmPassword”, and its PasswordChar property should also be changed to “*”. The textbox aligned next to the Email label should have its named changed to “registerEmail”. Change the buttons Text property to “Register”, and its Name property to “registerButton”.

Configuration Tab:
Make sure you have the Configuration tab clicked, and make 4 labels with 3 corresponding textboxes and 1 NumericUpDown. Change the labels text properties to “SMTP Address: “, “Port: “, “Email Username: “, and “Email Password: “. Next change their corresponding textboxes Name properties to “smtpAddressTextBox”, “smtpUserNameTextBox”, and “smtpPasswordTextBox”. Change the smtpPaswordTextBox’s PasswordChar property to “*”. Now drag the NumericUpDown next to the Port label and change its name to “smtpPortNumericUD”, and its Maximum property to “9999”.
Leave the Database tab blank for now, as we will get to that later.
The form should look like this:
Login Tab:
Posted Image
Register Tab:
Posted Image

Configuration Tab:
Posted Image

Creating a SQL Server Compact Database

Now we are going to create a database to hold all of our data. This database will contain the Table named logins, and that table will contain the Columns for holding all of our data. If you don’t see Data Sources on the left hand side of the IDE, go ahead and click View > Other Windows > Data Sources. Click the “Add new Data Source” icon in the top left, and it will bring up a new window asking you what type of data source you would like to create. Make sure “Database” is clicked, and then click next. This will bring up a screen to choose your database model. Make sure “Dataset” is clicked, and click the next button again. On this screen, it will ask you to choose your database connection. Since we haven’t made a database yet, we will have to click the “New Connection” button. This will bring up a new screen asking you to fill out our new connections information. Leave everything in the form default except for name. Name it “logins” and click the “Create” button. This will bring up a new screen to name and create your database. Leave everything on this page default, and click the OK button. It will ask you if you are sure you want to create a database without password protection. Normally with a login/register system you wouldn’t make the database without a password, but since I’m trying to keep things as simple as possible, we’ll do without a password. Click yes, and it will create your database for you. Click OK on the next page, and it will now show your new database in the selection box. Click the next button, and a message box will pop up asking if you would like to copy the new database file to your project. Click Yes, and it will take you to a new screen asking how you would like to save the connection string. Leave everything as default, and click next. Finally, click “Finish” and it will create a new, empty dataset for you.

Next, we will have to add data to our database. To do this, you will need to bring up the Database Explorer by clicking View > Other Windows > Database Explorer. Once you have brought this up, you will see your new database. Click the dropdown arrow on your database, right click on “Tables”, and click “Create New Table”. Name the Table “Logins”, and fill out the columns according to the information below:
Name: Username
Type: nvarchar

Name: Password
Type: nvarchar

Name: Email
Type: nvarchar

Once done, click the “OK” button. Go back to your DataSources panel, and click the “Configure data source with wizard” icon. This will bring up the Data Source Configuration Wizard. All you have to do here is check the “Tables” checkbox, and click “Finish”. This will load the Table into your logins dataset. Now, make sure that you have the Database tab selected on your form, and drag the Logins table from the Data Sources menu onto the tab. The table in which you are now looking at is called the DataGridView. On the DataGrid, click the menu arrow on the top right of it, and click the “Dock in parent container” button. This will fill your tab with the DataGrid.

The reason I am adding the DataGrid to the form is so that we can visually see that our program is registering users. Once we are positive that our server is registering, we can easily delete the Database Tab.

Adding functionality to our form
Before we begin, you need to add these using statements to the top of your code:

using System.Text.RegularExpressions;
using System.Net;
using System.Net.Mail;
using System.Security.Cryptography;



Finally we will start adding functionality to our form by adding some code! Because the Register event is the hardest to tackle, we will handle this first. Make sure the Register tab is clicked, and double click the “Register” button to bring up Form1.cs. It should have already written code for you to handle the click event for the Register button. Now, we have the option of writing everything we need inside of the button, but what if our program has other methods for adding users, other than the Register button? Like if an admin wants to manually add a user? For this, we could just create a new function called AddUser(). Make sure you are out of the Register button click event, but still within the Form1 class, and write this code:
        private void AddUser(string username, string password, string confirmPass, string email)
        {
            //Local variables to hold values
            string smtpEmail = smtpUserNameTextBox.Text;
            string smtpPassword = smtpPasswordTextBox.Text;
            int smtpPort = (int)smtpPortNumericUD.Value;
            string smtpAddress = smtpAddressTextBox.Text;

            //Regex for making sure Email is valid
            Regex regex = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$");
            Match match = regex.Match(email);

            //Loop through Logins Table
            foreach (DataRow row in loginsDataSet.Logins)
            {
                //And look for matching usernames
                if (row.ItemArray[0].Equals(username))
                {
                    //If one is found, show message:
                    MessageBox.Show("Username already exists");
                    return;
                }
            }

            //Confirm pass must equal password.
            if (password != confirmPass)
            {
                MessageBox.Show("Passwords do not match");
            }
            //Password must be at least 8 characters long
            else if (password.Length < 8)
            {
                MessageBox.Show("Password must be at least 8 characters long");
            }
            //If email is NOT valid
            else if (!match.Success)
            {
                MessageBox.Show("Invalid Email");
            }
            //If there is no username
            else if (username == null)
            {
                MessageBox.Show("Must have Username");
            }
            //If all is well, create the new user!
            else
            {
                loginsDataSet.LoginsRow newUserRow = loginsDataSet.Logins.NewLoginsRow();

                string EncryptedPass = HashPass(password);
                newUserRow.Username = username;
                newUserRow.Password = EncryptedPass;
                newUserRow.Email = email;

                loginsDataSet.Logins.Rows.Add(newUserRow);
                registerUserName.Text = String.Empty;
                registerPassword.Text = String.Empty;
                registerConfirmPassword.Text = String.Empty;
                registerEmail.Text = String.Empty;
                MessageBox.Show("Thank you for Registering!");
                if (String.IsNullOrWhiteSpace(smtpEmail) || String.IsNullOrWhiteSpace(smtpPassword) || String.IsNullOrWhiteSpace(smtpAddress) || smtpPort <= 0)
                {
                    MessageBox.Show("Email configuration is not set up correctly! \nCannot sent email!");
                    
                }
                else
                {
                    SendMessage(email.ToString(), username.ToString(), password.ToString());
                }
            }
        }


Notice the “string EncryptedPass = EncryptPass(password)” line.. Because of this line, if you ran your program you wouldn’t start because this would throw an error. This is because we haven’t built the EncryptedPass function yet. Let’s go ahead and build that right now. Add this function to your code:

 public string HashPass(string password)
        {
            SHA256 sha = new SHA256CryptoServiceProvider();

            //compute hash from the bytes of text
            sha.ComputeHash(ASCIIEncoding.ASCII.GetBytes(password + email));

            //get hash result after compute it
            byte[] result = sha.Hash;

            StringBuilder strBuilder = new StringBuilder();
            for (int i = 0; i < result.Length; i++)
            {
                //change it into 2 hexadecimal digits
                //for each byte
                strBuilder.Append(result[i].ToString("x2"));
            }

            return strBuilder.ToString();
        }



The first thing that we do in the AddUser() function is create a few local variables to hold all of the data contained within the text boxes that we made. The next thing we do is create a Regex string to make sure that the email addressed entered is in the correct format (i.e. email@domain.com). The next thing we do is loop through each row in the table, and check its username property [0] to see if it is already in use. If so, we pop up a message box indicating that the username is already in use. Next, we check to see if the first password entered is equal to the confirmation password. If not, we pop up a message box indicating that it must be equal. Next, we check to see if the passwords length is at least 8 characters long. If not, we pop up another message box indication that it must be at least 8 characters long. We then check to see if the email entered is not a match to our Regex format. If it isn’t, we will pop up a message box saying that it is an invalid email. Finally, we check to see if the username field is null (empty), if so then we pop up a message indicating that there must be a username.

If none of these errors are met, then we can add the account to our database. We first encrypt the password with our new EncryptPassword() function, and then we create a new row in our table filled with all of the data entered into the textboxes, set all of the textboxes back to blank, pop up a MessageBox thanking the user for registering, and finally we check to see if the smtp information is filled out. If not, then a messagebox pops up saying that we can't send an email because it's not filled out properly, if it is, we call the SendMessage() method that sends the user an email message. We have not created this function yet, so go ahead and click under the AddUser() method, and write this code:

        public void SendMessage(string ToAddress, string ToName, string password)
        {

            var client = new SmtpClient(smtpAddressTextBox.Text, (int)smtpPortNumericUD.Value)
            {
                Credentials = new NetworkCredential(smtpUserNameTextBox.Text, smtpPasswordTextBox.Text),
                EnableSsl = true
            };
            client.Send(smtpUserNameTextBox.Text, ToAddress, "Thank You!", "Thank you for registering with us today! \n Your username/passwords are: \n \nUsername: " 
                                                                        + ToName.ToString() + "\nPassword: " + password.ToString());
        } 



Making and calling these functions may have felt a little different than making and calling the functions in my last tutorial (Inventory Program). This is because these functions take parameters between the parentheses. Usually when calling a function from within another function, you will have to make it take parameters from that function. It is also best practice when making functions that will be reused a lot throughout your program. You could have made them equal to the textbox’s values but that may cause issues with the code later on.

Go ahead and make the registerButton click event look like this:

        private void registerButton_Click(object sender, EventArgs e)
        {
            AddUser(registerUserName.Text, registerPassword.Text, registerConfirmPassword.Text, registerEmail.Text);
        }




Now run your program, and try to add yourself. If the thank you messagebox shows up, it should have added you, but just to be sure go ahead and click the database tab and see if you have been added to the database. If so, go check your email and there should be a thank you email waiting for you! Make sure you’re not sending yourself an email from the email you used in the code. This may require you to create a new email address.

Next, we are going to tackle the loginButton click event. Go to the login tab and double click the login button to bring up the loginButton click event code. Go ahead and rewrite it to look like this:

        private void loginButton_Click(object sender, EventArgs e)
        {
            //Locals to hold values
            string username = loginUserName.Text;
            string password = HashPass(loginPassword.Text);


            //Loop through database
            foreach (DataRow row in loginsDataSet.Logins)
            {
                //And search for Username and Pass that match
                if (row.ItemArray[0].Equals(username) && row.ItemArray[1].Equals(password))
                {
                    loginUserName.Text = String.Empty;
                    loginPassword.Text = String.Empty;
                    MessageBox.Show("Login Success");
                    break;
                }
                //If not, then show this message.
                else
                {
                    MessageBox.Show("Username/Password incorrect");
                    break;
                }
            }
        } 


The first thing this code does is creates two local variables to hold the username and password that the user typed into the loginUserName and the loginPassword textboxes. Next, we use a foreach loop to cycle through all the rows in our Table and checks if the rows Username [0] value is equal to the username entered by the user, AND (&&) its Password [1] property is equal to the password entered by the user. If so, then we set the loginUserName and loginPassword textboxes Text properties to empty, pop up a MessageBox saying it was successful, and break the loop. Else, if any of these conditions were not met, then we have a MessageBox pop up saying that either the Username or Password entered was incorrect, and break the loop.

Now try and run your program, register for the program, and try to log in using the credentials you entered. If you get the “Login success!” messagebox, then you have made your first successful Login/Register system using C# and SQL Server Compact Edition. If not, then post any problems you may be having on this thread, or send me a PM asking me it.

This post has been edited by optix212: 27 April 2013 - 05:14 PM


Is This A Good Question/Topic? 4
  • +

Replies To: C# Login/Register system using SQL Compact

#2 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon


Reputation: 4488
  • View blog
  • Posts: 7,816
  • Joined: 08-June 10

Posted 24 April 2013 - 02:48 PM

Good tutorial, but very poor security practices on a few points:

  • MD5 is not secure. Switch to SHA-256, or better yet, use a hashing algorithm actually designed for passwords, like bcrypt or PBKDF2 (which is already implemented in C# as Rfc2898DeriveBytes). Personally I'd use BCrypt. There should be some implementations on NuGet.
  • Salt your password hashes. Unsalted hashes means that an attacker can generate a rainbow table and potentially compromise every single password your table has. When you properly salt each hash, a rainbow table can no longer be used against every password; you'd have to generate one for each individual password.


I'd also suggest renaming your EncryptPass method. You're not actually encrypting, you're hashing, which are two different things. Renaming isn't necessary for logic, just for understanding.
Was This Post Helpful? 1
  • +
  • -

#3 optix212  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 27
  • View blog
  • Posts: 509
  • Joined: 10-October 09

Posted 24 April 2013 - 08:22 PM

Ahh, thank you for the advice! I will start revising the tutorial asap.

Sorry for the lack of security, as that is not my area of expertise ^_^
Was This Post Helpful? 0
  • +
  • -

#4 Skydiver  Icon User is online

  • Code herder
  • member icon

Reputation: 3574
  • View blog
  • Posts: 11,114
  • Joined: 05-May 12

Posted 25 April 2013 - 06:52 AM

Another thing about security... use SecureString to hold passwords instead of a generic String: http://msdn.microsof...y/7kt014s1.aspx
Was This Post Helpful? 0
  • +
  • -

#5 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon


Reputation: 4488
  • View blog
  • Posts: 7,816
  • Joined: 08-June 10

Posted 25 April 2013 - 07:18 AM

See, I thought about mentioning that too, but the string would be in memory in the TextBox's Text property, so it's like closing the barn door after the cows got out.
Was This Post Helpful? 0
  • +
  • -

#6 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3473
  • View blog
  • Posts: 11,788
  • Joined: 12-December 12

Posted 25 April 2013 - 07:43 AM

View PostCurtis Rutland, on 25 April 2013 - 02:18 PM, said:

See, I thought about mentioning that too, but the string would be in memory in the TextBox's Text property, so it's like closing the barn door after the cows got out.

I thought it was a horse..?
Was This Post Helpful? 0
  • +
  • -

#7 bhattu  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 21-July 13

Posted 21 July 2013 - 11:40 PM

Can anyone provide me a link to guide c# from the scratch.

This post has been edited by Curtis Rutland: 22 July 2013 - 06:23 AM
Reason for edit:: removed needless quote

Was This Post Helpful? 0
  • +
  • -

#8 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon


Reputation: 4488
  • View blog
  • Posts: 7,816
  • Joined: 08-June 10

Posted 22 July 2013 - 06:24 AM

Sure. Start here:

http://www.dreaminco...%23-start-here/
Was This Post Helpful? 0
  • +
  • -

#9 nadadepao  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 08-September 13

Posted 08 September 2013 - 08:19 AM

mod:removed unnecessary quote.

Hello, i did it in a different way, i didn't put the tabs and blah blah blah, till there is all right, but i get errors about the db.
This is the error:

Error 4 An object reference is required for the non-static field, method, or property 'Launcher.loginsDataSet.Logins.get'

im only getting 4 errors because of this! And im a beginner i have no idea what to do!!!

This post has been edited by modi123_1: 08 September 2013 - 10:55 AM
Reason for edit:: removed giant quote

Was This Post Helpful? 0
  • +
  • -

#10 Rhino1111  Icon User is offline

  • D.I.C Head
  • member icon

Reputation: 99
  • View blog
  • Posts: 228
  • Joined: 28-August 13

Posted 10 September 2013 - 09:26 PM

again, mod removed unnecessary quote

I'm not trying to be rude here...but...
Why don't you try learning c# from the ground up? Trying to dabble in some of the more "advanced" tasks while having no foundation to work off of won't end well. The error message is quite self explanatory once you understand the basics and concepts of the language you're working with.

When you're learning to swim, you don't immediately jump into the deep end. You begin in the shallows where you won't drown, and build up the fundamentals that will allow you to swim in the deep end one day. The same applies to learning programming.

This post has been edited by Curtis Rutland: 11 September 2013 - 05:02 AM

Was This Post Helpful? 0
  • +
  • -

#11 Curtis Rutland  Icon User is online

  • (╯°□°)╯︵ (~ .o.)~
  • member icon


Reputation: 4488
  • View blog
  • Posts: 7,816
  • Joined: 08-June 10

Posted 11 September 2013 - 05:03 AM

Guys, please don't quote the post immediately before you. It's assumed that you're replying to either the original post or the last one. Any other post, it's ok to quote if you want, but if you're going to quote the last post, make it a small piece you want to address, not the whole thing.
Was This Post Helpful? 1
  • +
  • -

#12 Jozimental  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 13-September 13

Posted 13 September 2013 - 03:21 AM

i was trying this tutorial i get this error on this line
loginsDataSet.LoginsRow newUserRow = loginsDataSet.Logins.NewLoginsRow();

it says windowsFormApplication6 does not contains login defition
Was This Post Helpful? 0
  • +
  • -

#13 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3473
  • View blog
  • Posts: 11,788
  • Joined: 12-December 12

Posted 13 September 2013 - 04:56 AM

Please don't quote the entire tutorial.

What is the exact error message you receive?
Was This Post Helpful? 0
  • +
  • -

#14 Jozimental  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 13-September 13

Posted 19 September 2013 - 12:55 AM

Here is the error that I get

An object reference is required for non-static field,method or property windowsFormApplication6.LoginsDataSet.Logins.get
Was This Post Helpful? 0
  • +
  • -

#15 xaragk  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 03-October 13

Posted 03 October 2013 - 08:10 AM

this is a really well written article with much useful details..im new in c# so forgive me if i say anythng stypid.. im facing a problem which is forcing me to continue...
At this point: "and drag the Logins table from the Data Sources menu onto the tab. The table in which you are now looking at is called the DataGridView. On the DataGrid, click the menu arrow on the top right of it, and click the “Dock in parent container” button. This will fill your tab with the DataGrid."
i cant get which table i should drag...at the data sources i only have "loginsDataSet" which is not able to drag..(to drag it i just click the mouse and drag it right??)
Also i cant see any DataGridView or DataGrid but i suppose this is normal cause i havent done the previous step with the drag and drop...so i cant continue my project unfortunately...i would appreciate if u could help me..i also attach a printscreen if it helps you at all..thanks!
Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3