-2

I'm working on registration process with PHP. I managed to get submitted form data and save it into mysql table, but the problem is, if I refresh the page, user gets registered again. This is my PHP code which I have included in a div tag with other content:

<?php
    if(isset($_POST["registration"])){
            $con = mysqli_connect("localhost", "user", "pass", "name") or die("connection error");
      if (mysqli_connect_errno()){
        echo "Failed to connect to MySQL: " . mysqli_connect_error();
      }

      $name = $_POST["name"];
      $lname = $_POST["lname"];
      $email = $_POST["email"];
      $pass = $_POST["pass"];
      $company = $_POST["company"];
      $webpage = $_POST["webpage"];
      $phone = $_POST["phone"];
      $country = $_POST["country"];
      $city = $_POST["city"];
      date_default_timezone_set('Asia/Tbilisi');
      $info = getdate();
      $date = $info['mday'];
      $month = $info['mon'];
      $year = $info['year'];
      $hour = $info['hours'];
      $min = $info['minutes'];
      $sec = $info['seconds'];
      $reg_date = $year . "-" . $month . "-" . $date . " " . $hour . ":" . $min . ":" . $sec;
      $confirmed = "0";
      $success = mysqli_query($con, "INSERT INTO users(firstname, lastname, email, pass, company, webpage, country, city, phone, reg_date, confirmed) VALUES('$name','$lname','$email', '$pass', '$company', '$webpage', '$country', '$city', '$phone', '$reg_date', '$confirmed')");
      if($success){
            echo "You have been successfully registered. Use the form above to log in.";
        }
        else{
            echo "registration error";
        }
      //unset($_POST["registration"]);
    }
  ?>

I've also tried to unset the $_POST["registration"] as you can see, but it did not help. What should I do, to make this code work only when the "register" button is clicked?

P.S. I'm starting session in the beginning of the page, but not assigning any data to it.

Vaxo Basilidze
  • 1,017
  • 13
  • 31
  • You are open to SQL injections you should parameterize your query. Set a session value when it gets processed, if present don't allow it to rerun. – user3783243 Sep 04 '18 at 13:52
  • 3
    The standard way of dealing with this is redirecting the user to another page after saving the data so that refreshing will refresh that page, not the processing page. – Jonnix Sep 04 '18 at 13:53
  • 1
    `unset($_POST["registration"]);` doesn't work because when the page is refreshed, the post data is resent to the server. – webnoob Sep 04 '18 at 13:54
  • I know, I'm not checking input right now. I just need to fix the bug for now – Vaxo Basilidze Sep 04 '18 at 13:54
  • that is the browser capability, whenever you refresh the page the same data is posted automatically by browser. Better after signup redirect user to another page not on same page – RAUSHAN KUMAR Sep 04 '18 at 13:55
  • https://en.wikipedia.org/wiki/Post/Redirect/Get – Phil Sep 04 '18 at 13:56
  • 3
    **Warning:** Do NOT use this code on a production site, you are saving plain text passwords and are at risk for SQL injection attacks. – Devon Bessemer Sep 04 '18 at 13:56
  • _"I'm not checking input right now"_ <- it's more difficult to do later, trust me – Phil Sep 04 '18 at 13:57
  • @Devon I know, I'm planning to add input check for every field – Vaxo Basilidze Sep 04 '18 at 14:06
  • @VaxoBasilidze neither password hashing or injection protection has to do with "input checks for each field"... – Devon Bessemer Sep 04 '18 at 14:07
  • @user3783243 Here, I have covered my database from injection: $name = mysqli_real_escape_string($con, $_POST["name"]); Did this to all inputs. – Vaxo Basilidze Sep 04 '18 at 14:33
  • @Devon I have covered my database from injection: $name = mysqli_real_escape_string($con, $_POST["name"]); Did this to all inputs. – Vaxo Basilidze Sep 04 '18 at 14:34
  • 2
    That's not the right way to defend against injections. Always use prepared statements, that method has been outdated for over 5 years. https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php – Devon Bessemer Sep 04 '18 at 14:35
  • @Devon Ok, I'll take a look. I found an examples at w3schools, https://www.w3schools.com/php/php_mysql_prepared_statements.asp I'll use this method then – Vaxo Basilidze Sep 04 '18 at 14:45
  • 1
    Ok, be careful about what data you get from w3schools, I've seen a lot of outdated info on there over the years. I'd recommend finding a teacher or professional mentor to guide you on best practices rather than trying to find your own information. https://www.phptherightway.com/ is a pretty good site for best practices but I don't think they cover prepared statements. Don't forget about password hashing either, read the section on that site and the duplicate I linked above. – Devon Bessemer Sep 04 '18 at 14:50

1 Answers1

5

On success redirect the user to another url

header('Location: '. $url);
die();
  • What should I do if my project has single page? – Vaxo Basilidze Sep 04 '18 at 14:07
  • The main goal is to clean the $ _POST variable, since a system variable can not be set, you have to do it implicitly. So you can also redirect the page to itself. – Francesco Simeoli Sep 04 '18 at 14:22
  • Will it work if I set to form action attribute: action="" – Vaxo Basilidze Sep 04 '18 at 14:30
  • If it's a single page, consider using AJAX instead. – webnoob Sep 04 '18 at 14:37
  • No, you need to make a new request to the server. To show a message like "Congratulations now you are registered!" you can add in the redirect url a query string and than check the variabile in the next request, or use a flag using $_SESSION (in both cases you have to clean the "state" variable). Alternatively use ajax for the registration request (as suggested by @webnoob). – Francesco Simeoli Sep 04 '18 at 14:45