Signup and Login with PHP and MySQL

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video you're going to learn how to  create this site using php a sign up page   including validation that saves the details to  a mysql database then a login and logout page all the code developed in this video is freely  available and the link is in the description   let's start by creating the signup  form so let's create a new file   called signup.html we'll use the html suffix  as this particular file won't contain any php   in here we'll put the doctype html  head and body tags inside the head   element let's add a title and a meta tag  to specify the character set as utf-8 inside the body element let's add a heading   and a form tag inside the form we'll start with  a text input for the name and an associated label   we associate the label to the input with the  for attribute on the label and an id attribute   on the input with the same value we'll also add  a name attribute to the input so that its value   will be sent when the form is submitted finally  we'll wrap these two elements in a div element   this will show each label and input pair on a  separate line plus will also be useful later on   when we add client-side validation next let's add  an email type input for the email address as with   the input above we'll add an associated label a  name attribute and we'll enclose this in a div tag   to keep it simple we'll be using the email  address to uniquely identify each user account   you can add a username if you prefer in which case  you'd need to add a text input to this signup form   next we'll add a password  type input for the password   again as above we'll add an associated label a  name attribute and we'll enclose this in a div tag before we go any further let's see how this  looks so far if we open this file in the   browser there's the heading and the three inputs  we've added so far with their associated labels   as the password field is a password input when we  enter text into it we can't see what we've typed   only placeholder characters this is so no one  can see what we've typed for this reason it's   common practice to include a password confirmation  field where the user has to enter the same value   again to reduce the likelihood of the user  typing in their desired password incorrectly   so let's add another password type input but with  different values for the id and name attributes finally in the form we'll add a submit button in the browser there's the form to add some  styling to this instead of developing some css   from scratch we'll use an existing style sheet  when doing back end development the simplest   way to add styling to html is to use a classless  stylesheet this means we don't have to add any   classes or extra elements to the html there  are many classless css frameworks available   my current favorite is water.css to use  this we just copy this link tag code   and paste it in the head section of the html now in the browser the signup form is nicely  styled just by adding one line of code to the html   next let's add a script to process  this form when it's submitted   let's add a new file called processsignup.php before we add any code in here we'll  add an action attribute to the form tag   containing the name of this new script so that  when the form is submitted this is where its data   will be sent while we're here we'll also add  a method attribute specifying the post method   this is the method to use if you're saving data  on the server which is what we'll be doing shortly   back in the process sign up script let's start  by adding the php opening tag just to make sure   we're getting the data from the form correctly  let's just print out the post super global in the browser if we enter some  data into the form and submit it we get the values we entered printed out the array  keys are the values from the name attributes of   the various inputs before we save this data  let's validate it we'll start with the name   if the name element of the post array is empty  we'll just stop the script with a suitable message   later on we'll add some more user-friendly  validation in the browser using javascript   so it's not necessary here to re-display  the form this validation is just for the   unlikely event that the client side validation is  bypassed so it doesn't need to be more than this let's give that a try if i submit the form  with no value for the name we get the message if i enter a value then we get the form data  printed out as before next let's validate the   email address to do this we'll use the filtervar  function with the email validation filter this   returns false if the value passed in isn't a valid  email address so if this is false we'll output a   message as above before we try this let's just  disable the html validation in the form by adding   the no validate attributes to the form tag as  we're using an email input type the browser will   validate this as an email address so we can test  the server side validation we need to disable this let's give that a try if i submit  anything other than a valid email address   we get the message printed out  if it's a valid email address the validation passes now we can validate the password first let's  check that it's at least eight characters   long which we can do using  the string length function then we'll check that it contains at least one  letter which we'll do using the pregmatch function   this matches the value to this regular  expression this will match any single lower   or upper case letter this will return false  if it doesn't match so we can check for that then we'll use the same technique to check  the password contains at least one number let's give that a try if i enter  a password that's too short   or one that doesn't contain a letter  or a number then validation doesn't pass it only passes if i enter a valid password finally let's validate the password confirmation  field for this we simply check that the password   field is equal to the password confirmation field  if it isn't we'll output a message as before let's try that and we see the  validation if the passwords don't match now we have valid data for a user account that we  can save however before we do that note that we   don't want to save the password in clear text like  this this is because if an attacker gets hold of   the database they then have a list of emails and  passwords they can use to log into the site also   as people reuse the same email and password  on different sites the attacker could use   these credentials to log into other sites  too instead we store the password as a hash   we can generate a hash from a plain text  password using the password hash function   this can use various different algorithms  but it's simplest just to use the default so let's call that function  passing in the value from the form   and the default password flag this will  return the hash of the password as a string   so let's assign that to a  variable and print it out let's give that a try when i submit valid  data there's the hash of the password in   this case a 60 character string of seemingly  random characters if all you have is this hash   value there is no way to extract the original  plain text password from it so it's very secure   now we have the data we want to save we  can create a database table to store it in i'll do this in phpmyadmin first let's create a  new database called logindb accepting the default   collation then we'll create a table in this  database called user that will have four columns we'll call the first column id which is an integer   and we'll check the auto increment checkbox  which will also make this the primary key the next column will be for the name and  we'll make this a 128 character varchar next the column for the  email address which will make   a 255 character varchar and we'll also  specify a unique index on this column   this means that no two rows can  have the same value for this column the next column will be for the password  hash which we'll call password hash although the hash that we saw earlier was  only 60 characters the documentation for the   password hash function recommends storing  this in a field that's 255 characters long   as the algorithm could change over time and the  hash it returns could be a different length so   we'll create this field as a 255 character varchar  we'll save that and there's the database table now we can connect to the database from php  as we're eventually going to be connecting   to the database from more than one place let's  add a new file that will contain the database   connection code so we'll create a new file called  database.php and in here we'll start with the php   opening tag next let's create some variables to  contain the connection details for the database   the host is the same as the web server  localhost the name of the database we   just created is logindb and will connect using the  root account which by default has a blank password   note that connecting with the root account like  this is only recommended when developing locally   to connect to the database we'll create a new  mysqli object passing in the host username   password and database name these variables have  to be in this order and it's a common error   to get them in the wrong order if you prefer  you can use named arguments by prefixing each   value with the name of the argument if you do  this it doesn't matter which order they're in   before we can use this database connection we need  to make sure we connected ok the connect error   number property of the mysqli object is set to an  error code from the most recent connection attempt   if there was no error this is zero so we can check  for this by simply using this as the condition for   an if statement if a connection error has occurred  we'll stop the script and print out a message   we can get a description of the error in  the connect error property finally in this   script we'll return the mysqli variable back  in the process signup script let's require the   database.php script we just added using the dir  constant to get the directory of the current file   as we put a return statement at  the end of the database script   this will be what is returned from the require  statement so we can assign that to a variable let's give that a try if i submit valid data  then we get the form data printed out as before   this means we've connected to the database  successfully as there was no error displayed   to check the error handling code let's  temporarily change the database password and now if i refresh the page in the browser  we get the connection error displayed   this is the message you'll get  if the connection credentials   are incorrect let's just change  that back so it's correct again now we've connected to the database we can  insert a new record into the user table   we'll use a prepared statement for this as this  will allow us to avoid an sql injection attack   first let's write the sql we'll use an sql  insert into statement specifying the name   email and password hash fields the id field is  an auto increment field so if we don't specify it   a value will be inserted automatically  for the values we'll use placeholders   then we'll create a new prepared statement  object by calling the statement init method   on the mysqli connection object next we  prepare the sql statement for execution   by calling the prepare method on the statement  objects passing in the sql string as an argument   it's at this point that any syntax errors in the  sql will be caught if the prepare method returns   false then there's a problem with the sql to  catch this we can check for the return value   and if it's false we'll stop the script and  display the error detail which we can get   from the error property of the connection object  to test this let's add a typo to the sql string and when we refresh the page in  the browser we see the error detail   let's change that back to get rid of the error now  we have the statement ready to execute we can bind   values to the placeholder characters to do this we  call the bind param method on the statement object   the first argument is a string that contains  characters that specify the types of the variables   as all three variables are strings  the string is three s characters we   follow this string with the actual values  which are the name email and password hash   finally to execute the statement we call  the execute method on the statement object   following this instead of printing out the form  data for now let's just print out a message let's give that a try if i enter valid data  into the form and submit it we get the sign   up successful message if we have a look in the  database there's the record in the user table   note the value for the id column has been  generated automatically note what happens though   if we go back to the form and submit it again with  exactly the same details we still get the sign   up successful message but no additional  record is inserted into the database this   is because we added a unique index  on the email column in this table   that prevents more than one record having the  same value in this column so what we should   do in this case is add some validation on the  email address that prevents us from displaying   the success message if a record with that email  address already exists in the database the execute   method returns true if it was successful and  false otherwise so let's check for that and if   it's false for now let's just print out the error  message as we did above in addition to the error   description though let's also add the error code  which we can get from the error number property now if we submit the form with the  same details we get a description   of the error we can improve this a step  further by detecting the specific error   as we can see the error code for this specific  error a duplicate key entry error is 1 0 6 2.   so before this statement where we stop  the script and display the error message   let's check the error number property  and if it's equal to 1.062 we'll stop   the script with a more specific error message  and otherwise we'll just continue as before if we submit the same details again now  we get the specific validation message   if there's some other problem then we'll  get the error details for that printed out   if i go back and change the email address to one  that doesn't already exist in the database then   we get the sign up successful message note what  happens if i refresh the page at this point we   get a warning about a repeat form submission and  if we accept it the form's data is submitted again   and we get the email validation error message to  avoid this we'll use the post redirect get pattern   so instead of just echoing out this message  if the sign up is successful at this point   we'll redirect to another page so first let's  create a new file called signupsuccess.html to keep this simple i'll just copy the first  part of the signup.html file and paste it in the   sign up success file after the heading tag we'll  just add a paragraph tag containing the sign up   successful message and then we'll close the body  and html tags back in the process signup script   instead of outputting the message in here we'll  use the header function to send a location header   with the address of the sign up success file we  just added as we are redirecting at this point   it's good practice to exit the script  immediately once we've sent the header   let's give that a try with valid data in the form  making sure i specify an email address that i know   doesn't exist in the database when i submit the  form we get redirected to the sign up success page   note that if i refresh this page no warning  is given about the form data being resubmitted   now that a user can sign up we  can add a page for them to log in let's add a new file called login.php we'll be putting some php code in  this script so it needs the php suffix   we'll start with the html for the login form   as before to keep it simple we'll just copy the  start of the html from the sign up page and paste   it in the login script although we'll change the  contents of the title and header elements to login   we'll add a form then the  closing body and html tags   inside the form we'll add an input for  the email address and an associated label then the equivalent for the password and finally in the form a submit button before  we have a look at how this looks in the browser   let's add a link to this page  to the sign up success page in the browser now the sign up success  page has a link to the login page   if we click it we see the login form instead of submitting the form to a separate  script like the signup form will process this   form in the same script so we don't need  to add an action attribute to the form tag   but we will add a method attribute to specify the  post method then at the top of the file before the   html we'll add the php opening and closing tags  to detect if the form has been submitted we can   check the request method when we first click on  the link to open the page the method will be get   when the form is submitted with the button it  will be post when the form is submitted we need   to check that the email and password entered  into the form match one of the records in the   database we'll start by connecting to the  database by requiring the database.php file   then we'll write the sql to select a record  based on the email address remember any column   used in a where clause should have an index as  we do on the email column instead of using a   prepared statement for this we'll just insert  the value for the email directly into the sql   as the email is a string we need to enclose it  in single quotes in the where clause to insert   the value from the form we'll use the s printf  function putting a string placeholder in the   string where we want the value to go and passing  in the value from the post array as the second   argument of the function to make sure we avoid an  sql injection attack we need to escape the value   coming from the form we can do this with the real  escape string method of the mysqli object then   to execute this sql we call the query method on  the mysqli object passing in the sql this returns   a result object so we'll assign that to a variable  to get the data from the result object we call the   fetch a sock method this will return the record  if one was found as an associative array so we'll   assign that to a variable for now let's print out  the contents of that variable and exit the script   let's give that a try if i don't enter anything  then we get null if i enter an email address that   i know doesn't exist in the database then we also  get null if i enter an email address that i know   exists in the database then we get an associative  array containing the data from that record so instead of printing this out let's  check that the user variable contains   an array of data and isn't null which  we can do with a simple if statement   if a record was found for that email address then  we can check the password we're getting the plain   text password from the form but the value  stored in the database is the password hash   to verify that the hash matches the plain text  password we use the password verify function this returns true if they  match and false otherwise   so let's check for that and for now we'll  just print out a message and stop the script now if i enter the correct details in the login  form we're shown the login successful message however if the credentials aren't correct  we're just shown a blank login form again   we can make this a bit more user-friendly   first let's show a message telling the user that  the login was invalid at the top of the script   let's add a variable called is invalid that  will set to false then at the end of the if   block that's executed when the form is submitted  we'll set this to true if we've reached this   point in the script the form has been submitted  but either the email or password was invalid   then in the html if this variable is true we'll  display a message saying the login was invalid   note that it's common practice to just say the  login was invalid rather than specifically the   email or the password this is to give as little  information as possible to a potential attacker   let's give that a try when we first view the  form no message is shown if i submit invalid   credentials we see the invalid login message  note what happens though with the email address   if the login is invalid the form is redisplayed  but the email address field is blank again   it's most likely that the user got the password  wrong and not the email address as the password is   masked when it's typed in so it would be more user  friendly if we keep the value of the email input   when redisplaying the form to do this let's  add a value attribute to the email input   specifying the email element of the post  array when we first load the form this will   be empty so we'll use the null coalescing  operator to default this to an empty string   as this is untrusted content we also need to  escape it using the html special charge function now if we enter an email in the form and submit  it the value is remembered when the form is   redisplayed if i enter valid credentials  we're shown the login successful message instead of showing this message  we can now log the user in   to do this we'll store the user id in a session  sessions are used to remember values between   browser requests php handles this automatically  by generating and storing a unique session id   in a browser cookie that's used  to uniquely identify the user   before we do this in here let's add a new file  where we can show if the user is logged in or not   so let's add a new file called index.php  and add the php opening and closing tags   in here in order to use the session we call the  session start function this will either start a   new session or resume an existing one once the  session is started we can store values in the   session super global and they'll persist across  requests so for now let's just print that out if we open the index.php page in a browser  we just get an empty array printed out back in the login script instead of printing  out this message we'll start our resume the   session then store the user id in the session  super global by default these values are stored   in files on the server so it's best practice  to just store a small amount of information   in the session once we've done this let's  redirect to the index page and exit the script let's give that a try on the index  page the session array is empty   if we go to the login page and log in with valid  credentials we're redirected to the index page and   now the session array contains the id of the user  if i refresh this page then the value persists now we can quickly add some html to the index  page first again to keep it simple we'll copy   the head section of the html from the login page  and paste it after the php in the index page   changing the contents of the title and header  elements following this let's check to see if   the user id is set in the session and  if it is we'll just output a message if it's not set let's display links  to the login and sign up pages finally we'll add the closing body and html tags   and at the top we'll remove this line  that's printing out the session array let's give that a try if i refresh the  page from before we get the logged in   message to check how this looks when we're not  logged in we need to add logout functionality   so let's add a new file called logout.php in here we'll add the php opening tag then  to destroy the session we call the session   destroy function once we've done that  let's redirect back to the index page   note how we don't need the php closing  tag in here as this file just contains php   and how we don't technically need an exit  line as is the last line of the script but   it's good practice to always include  this after sending a location header   in the index page let's add a link to this inside  the block that's shown when the user is logged in let's give that a try if i refresh the page  now we see the logout link however if i click   it nothing happens we get redirected back to  the index page but we haven't been logged out   in the out page although we're calling the session  destroy function what i didn't include was a call   to the session start function first any time you  use the session you need to call session start   so let's add that and now when i click the logout  link we're redirected back to the index page   and we've been logged out if we log in again we're shown the logged in  message on the index page   let's make this a bit more user-friendly  and display the name of the logged-in user so in the index page after we've started the  session let's check for the user id value in the   session array if this is set we can retrieve the  user record from the database that corresponds to   this id so we'll require the database script  to get the connection then write the sql   to select the user record where the id equals the  value in the session this value isn't untrusted   content as it's a value we've set in the session  ourselves so we don't need to escape it then we'll   run that using the query method on the mysqli  object passing in the sql to get a result object and finally we'll get an associative  array containing the records values   using the fetch a sock method and assigning  this to a variable then in the html   instead of checking the session we'll just  check to see if the user variable is set then   instead of outputting this message we'll print  out a greeting that includes the user's name   making sure we escape it with the html special  charge function as its untrusted content   before we try this there's one more thing that we  need to add to the login page as we're starting   the session at the top of the index page when we  load the login page the session will already be   started this could make the code vulnerable to a  session fixation attack to avoid this once we've   logged in successfully we regenerate the session  id by calling the session regenerate id function let's give that a try if i refresh the page once  we're logged in we see the personalized message   that covers the basics of how to sign up  and log in with php however we can make   the sign up page more user-friendly by adding  some client-side validation using javascript to do this i'll use the just validate javascript  validation library this has no dependencies and   is available on a cdn so all we need to do  to include it is to copy this script tag and paste it in the head  section of the sign up form   let's also add a new file that will  contain the custom javascript for this page   first let's add a new folder called js then  inside here a new file called validation.js then back in the sign up page let's add another  script tag after the one we just added to load   this file let's also add defer attributes to these  two so that we ensure they're loaded in order i won't go into detail on how this library works   as the documentation here is comprehensive  and is there if you need to refer to it   first so that we can easily identify the form  let's add an id attribute to the form tag   then in the validation.js file we'll  create a new just validate object   passing in the selector for the form next  we can add validation rules for each field   let's start with the name we call the  add field method on the validation object   with the field selector as the first  argument and an array of rules as the second   each rule is an object where we can specify one of  the libraries library's built-in rules using the   rule property with the name of the rule as the  value for the name let's just make it required before we add any more rules let's try  that to make sure it's working so far   in the sign up form now if i try to submit  it with an empty name we get the required   field validation message printed out  below the input and the input focus   is placed in that input if i type a  value the validation message is removed next let's add some validation on the email input   we'll make it required and also  that it's a valid email address in the browser now the email field is required  and also needs to be a valid email address next the password which we'll make required and also use the password rule which requires  the password to be at least eight characters   and contain at least one  letter and at least one number in the browser now the password is validated next we'll validate the  password confirmation input there isn't a built-in rule to validate that  two fields are equal but we can add a custom   validation rule with the validator property the  value is a function that takes two arguments   the value of the input being validated and  an array of the other fields in the form   if we return true from this function then  it's considered valid and invalid if false   is returned so we can just return the result  of comparing the equality of the field value   and the value of the password field let's  also specify a custom error message for   when this field is invalid which we  do using the error message property in the browser now the password confirmation field  is validated to match the password once all the validation has passed we need  to manually submit the form as the validation   library has prevented this default behavior do  this by calling the onsuccess method passing   in a callback function in this function we'll get  the form element and call the submit method on it in the browser now if the validation passes  the form submits again   however one thing we're not validating  is that the email address isn't taken   if i submit the form again with the same details  we get the server side email validation message to validate if the email address is available  or not we have to check this in the database   so we'll have to make a request to the  server first let's create a new file   called validateemail.php and put in the  php opening tag in here all we want to do   is check the user table to see if a record  already exists with a given email address   so first let's connect to the database by  requiring the database file then we'll write   some sql to select any records from the database  where the email is equal to a value that will pass   in using the query string we'll use the s printf  function to insert the value from the query string   into the sql making sure we escape it  then we'll run it using the query method to see if the email address exists we can  check the number of rows in the result set   and if this is 0 the email address is available  so we'll assign that boolean value to a variable   as we'll be making this request from  javascript we'll output this as json   so let's add the json content type header  and output the is available variable as json before we call that from javascript  let's test it in the browser   we'll call the validate email script passing  in an email address in the query string   this email address already exists in the database  so we get some json that says this isn't available if i try an email address that doesn't exist in  the database we get true now we can call this   from the javascript validation code as with the  password confirmation field we'll add a custom   validator to the email field we don't need  the fields argument to the callback function   as all we need is the value of the field inside  this function we'll make a request using fetch   to the script we just added we'll add the value  of the field from the form in the query string   making sure we uri encode it this returns a  promise object so we can then call the then method   on that passing in a function to pass the json  response and return this as a javascript object   this in turn returns a promise object so we  can call then on that passing in a function   that simply returns the value of the available  property which will be true or false as we just   saw in the browser finally we'll return this  promise from the custom validator function   in addition to the custom validator  let's also add a custom error message let's give that a try if i enter an email  address that already exists in the database   we get the email already taken message if  i change it to one that doesn't exist in   the database the validation passes and  we see the sign up successful message note this client-side validation doesn't  replace the server-side validation it's   important to always have server-side validation  as the client-side validation can be bypassed   so now you know how to create signup login  and logout using php sql html and javascript   there's a link to all the code shown  in this video in the description   along with links to sites shown  and relevant documentation   please don't forget to like comment and  subscribe and as always thank you for watching
Info
Channel: Dave Hollingworth
Views: 158,992
Rating: undefined out of 5
Keywords:
Id: 5L9UhOnuos0
Channel Id: undefined
Length: 43min 16sec (2596 seconds)
Published: Mon Apr 11 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.