0

I am attempting to create a login page, in which, every attempt at a login is done on the page, straight away; rather than refreshing the page. Something along the lines of how Google do their login page, and how Facebook submit messages without refresh.

I have programmed the backend functionality of the page in PHP and now I would like to give it that little more to make it look and function exceptionally.

This is the current Ajax script I am using which doesn't want to work the way I would like it to (I have tried multiple others with the same results):

<script>
    $(function () {
        $('#_js_pdTr1').on('submit', function (e) {

            e.preventDefault();

            $.ajax({
                type: 'post',
                url: 'login_push.php',
                data: $('#_js_pdTr1').serialize(),
            });
        });
    });
</script>

This is the form for the page:

<form id="_js_pdTr1" action="" method="post">
    <h3>LOGIN</h3>
    <div class="err-disp-out">
        <?php
            if(!empty($errors)){
                echo output_errors($errors);
            }
        ?>
    </div>
    <input type="text" name="username" placeholder="Username"><br><br>
    <input type="password" name="password" placeholder="Password"><br><br>
    <input id="remember" type="checkbox" name="remember_me"><label for="remember">Remember Me</label><br><br>
    <button id="_js_pdTr2" type="submit">Login</button>
</form>

and on my login_push.php page, this is the PHP:

include 'core/init.php';
logged_in_protect();

$user = $_POST['username'];
$pass = $_POST['password'];

$user = preg_replace("/[^a-z0-9_\s-]/", "", $user);
$user = preg_replace("/[\s-]+/", " ", $user);
$user = preg_replace("/[\s_]/", "-", $user);

if(!empty($_POST)){
    if(isset($user) && isset($pass)) {
        $result = mysqli_query($conn, "SELECT * FROM users WHERE username = '$user'");
        if(mysqli_num_rows($result) == 0) {
            $errors[] = 'The username or password are incorrect.';
        } else {
            $passR = mysqli_query($conn, "SELECT * FROM users WHERE username = '$user'");
            while($row = mysqli_fetch_array($passR)){
                $dbHash = $row['password'];
                if(password_verify($pass, $dbHash)){
                    $activeQ = mysqli_query($conn, "SELECT active FROM users WHERE username = '$user'");
                    while($row = mysqli_fetch_array($activeQ)){
                        $active = $row['active'];
                        if($active == 0){
                            $errors[] = 'This user has not activated their account.';
                        } else {
                            $remember_me = ($_POST['remember_me'] == "on") ? 1 : 0;
                            if(isset($_POST['remember_me']) && $remember_me == 1){
                                $_SESSION['user_log'] = time() + 7889238;
                            } else {
                                $_SESSION['user_logi'] = time() + 3600;
                            }
                            $_SESSION['user_id'] = $user;
                            header('location: ./user');
                        }
                    }
                } else {
                    $errors[] = 'The username or password are incorrect.';
                }
            }
        }
    } else {
        header('location: ./');
    }
}

Pretty much, what I would like is:

When the form is submitted, it will push all the data from the form to the login_push.php page, and the PHP on that page will continue to run.

It will query the database and send information back to the original page and if the variable $errors is not empty, it will automatically echo it on the page (echoed on line 6 of the form code block), without refreshing the page. However, if the variable is empty, it will log them in!

All help is appreciated,

Cheers!

EDIT: I have already tested the other code out, however, It did not work the way I would like it to.

9
  • why on('#_js_pdTr2',??? You can use submit here. Commented May 23, 2016 at 9:13
  • @FrayneKonok when that specific ID button Is clicked, it will continue out with the Ajax. Commented May 23, 2016 at 9:14
  • Possible duplicate of Call php function from javascript Commented May 23, 2016 at 9:14
  • @FrayneKonok really? I wanted to be a little more specific with the submission button Commented May 23, 2016 at 9:15
  • @David'mArm'Ansermot already looked, didn't work as expected. :/ Commented May 23, 2016 at 9:15

1 Answer 1

2

Do not use header('location: ./user'); in your ajax. You have some duplicated code, like $result = mysqli_query($conn, "SELECT * FROM users WHERE username = '$user'"); Why do not you call it only once?

You are vulnerable to mysql injection, because you do not escape your variables.

You are set the $username from $_POST and after that you've checked ths isset($_POST), why is it?

Anyway, you need to echo a success / failed, or a JSON object with error and message keys.

$result = [
    'error' => 0,
    'message' => ''
];
//You can do other validations here
if (!empty($_POST)) {

    //Do the dbhash here
    $sql = "SELECT COUNT(*) AS cnt FROM `users` WHERE `username` = '" . mysqli_real_query($conn, $_POST["username"]) . "' AND `password` =  '" . password_verify($_POST['pass'], $dbHash) . "'";
    $res = mysqli_query($conn, $sql);
    $row = mysqli_fetch_row($res);
    if ($row['cnt'] < 1) {
        $result = [
            'error' => 1,
            'message' => 'Bad username or password'
        ];
    }
    //You can add success message if you want
}
echo json_encode($result);

And in your javascript:

$.ajax({
    type: 'post',
    url: 'login_push.php',
    data: $('#_js_pdTr1').serialize(),
    success: function(response) {
        if (response.error != 0) {
            //Show error here
        } else {
           window.location.href = './user'; //Better to use absolute path here
        }
    }
},'json');
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks! I'll test this out in a sec and get back to you! :) also, I'll have a look into that SQL injection stuff
What is $row['cnt'] for? I don't use this.
Also, how am I to output $errors[]? And how can I do the password verify?
$row['cnt'] is come from the query: COUNT(*) AS cnt. It asks, is there any user with this password? If there is, COUNT will return 1. You no need to use my $result if you want to use your errors[] array, you can. In this case, echo json_encode($errors);, and you can iterate through on that array.
Ah, ok I kind of get it now! Thank you :) is there any way of still checking if the user is active or not? Still very new to PHP and could use some tips! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.