-1

So I have a small user registration form that asks for a username and password built with React. I then send these fields to an insert.php file to add a user to a mySQL database. In the insert.php file I look for any repeat usernames and want to be able to return a message back to my react page. The insertion of users works but cannot return back to initial page from php file if duplicate username is found.

submitting form data to php file:

onSubmit(e){
    e.preventDefault();
    if (this.state.password === this.state.passwordConform) {
    const obj ={
      username:this.state.username,
      password:this.state.password,
      passwordConform:this.state.passwordConform,
    };
    axios.post('http://localhost/reactProject/insert.php',obj)
    .then(res=> console.log(res.data))
    .catch(error => {
      console.log(error.response)
  });

insert.php:

<?php
require 'connect.php';
header("Access-Control-Allow-Origin: http://localhost:3000");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");

function isAvailable($username, $db) {   //seeing if there is duplicate username
    $sql = "SELECT username FROM users WHERE username='$username'" ;

    $result = mysqli_query($db,$sql) ;
    if( mysqli_num_rows( $result ) > 0 )
    {
        return false;
    }
    return true;
}

$postdata = file_get_contents("php://input");
if(isset($postdata) && !empty($postdata)){
    $request = json_decode($postdata);
 
 
    $username = $request->username;
    $password = $request->password;


    if($username && $password && isAvailable($username, $db)) {
        $sql = "INSERT INTO users (username,password) VALUES ('$username','$password')";
        if(mysqli_query($db,$sql)){
            http_response_code(201);
        }
        else{
            http_response_code(422);
        }
     
    }
    else { //error in an input field, just trying to return to a page on my site from php
    
        header('Location: ../login');
        exit();
    }
}

?>

the php file is within Applications/XAMPP/htdocs/reactProject

the actual react code is in User/React/project_name

I have tried things like header('Location: http://3000/login') which is the exact url of the page i'm wanting to go to. If I type that location directly in my browser it successfully reaches that page. but it will not work from the php file

M. Eriksson
  • 13,450
  • 4
  • 29
  • 40
  • 4
    You can not redirect the frontend via the response to a _background_ request. Your client-side scripting logic needs to handle any sort of "redirect" you want to perform, based on the server's JSON response. – CBroe Nov 07 '22 at 07:49
  • 5
    **Warning!** You're open to [SQL injection attacks](https://owasp.org/www-community/attacks/SQL_Injection)! Read [how to prevent SQL injection in PHP](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) by using prepared statements with bound parameters instead of injecting variables directly into your queries. It's not just about security. If your data contains, for example, a single quote `'`, your query will break. – M. Eriksson Nov 07 '22 at 07:50
  • 4
    **Warning!** Never store passwords in plain text! You should only store password hashes generated using [password_hash()](https://www.php.net/manual/en/function.password-hash.php) and to verify a password againts a hash, use [password_verify()](https://www.php.net/manual/en/function.password-verify.php). – M. Eriksson Nov 07 '22 at 07:50

1 Answers1

1

As CBroe suggests, you need to handle the redirect in react.

So do something like this in your PHP code:

else { //error in an input field, just trying to return to a page on my site from php
    
        http_response_code(400);
        $inputerror["message"] = "Error in input field, probably a duplicate username";
        echo json_encode($inputerror);
        exit();
    }

Then in react you can handle the 400 status code or the specific message in the JSON body, using React Router's useNavigate to take the user back to the login page, something like this:

import { useNavigate } from "react-router-dom";
const navigate = useNavigate();
.....
onSubmit(e){
    e.preventDefault();
    if (this.state.password === this.state.passwordConform) {
    const obj ={
      username:this.state.username,
      password:this.state.password,
      passwordConform:this.state.passwordConform,
    };
    axios.post('http://localhost/reactProject/insert.php',obj)
    .then(res=> console.log(res.data))
    .catch(error => {
      console.log(error.response)
      if(error.response.status === 400) {
         navigate("/login");
      }
  });

You'll probably want to flesh out some logic on the login page to display the error to the user, perhaps using a query param or some other method of passing the prop to the login page.