1

I'm very new to ajax, and I'm trying to make a login script that doesn't require a page reload - it's working well except I attempt to set a session variable on the processing page, but no session variable is set.

My form:

<div class="form-bottom">
    <form role="form" class="login-form">
        <div class="form-group">
            <label class="sr-only" for="username">Username</label>
        <input type="text" name="username" placeholder="Username..." class="form-username form-control" id="username">
        </div>
        <div class="form-group">
        <label class="sr-only" for="password">Password</label>
        <input type="password" name="password" placeholder="Password..." class="form-password form-control" id="password">
        </div>
        <input type="submit" id="submit" class="btn" style="width:100%;background-color:lightblue;" value="Log In" id="login"/>
    </form>
        <? echo $_SESSION['Name']; ?>
</div>

My ajax:

<script type="text/javascript" >
      $(function() {
          $("#submit").click(function() {
          var username = $("#username").val();
          var password = $("#password").val();
          var dataString = 'username='+ username + '&password=' + password;

        if(username=='' || password=='')
        {
          $('.success').fadeOut(200).hide();
          $('.error').fadeOut(200).show();
        }
        else
        {
          $.ajax({
            type: "POST",
            url: "ajax/login.php",
            data: dataString,
            success: function(){
             $('.success').fadeIn(200).show();
             $('.error').fadeOut(200).hide();
             window.setTimeout(function () {
                location.href = "index.php";
            }, 3000);
            }
          });
        }
        return false;
        });
    });
    </script>

My php script:

 include('./static/config.php');

if (session_status() == PHP_SESSION_NONE) {
        session_start();
    }

if(isset($_POST)) {

    $username = mysqli_real_escape_string($con, $_POST['username']);
    $password = mysqli_real_escape_string($con, $_POST['password']);

    $sql = "SELECT Name FROM techs WHERE Username='$username' AND Password='$password'";
    $result = mysqli_query($con, $sql);
    $exists = mysqli_num_rows($result);

    if($exists == 1) {
    $row = mysqli_fetch_assoc($result);
        $_SESSION['Name'] = $row['Name'];
    }

}
GrumpyCrouton
  • 8,171
  • 5
  • 29
  • 65
  • 1
    Have you started a session? – Tyr Jan 14 '16 at 21:56
  • I always hate to ask this, but has the session been started? 9.9 times out of 10, they say "yes" but don't post the code for it. – Funk Forty Niner Jan 14 '16 at 21:56
  • do you have `session_start()` in all your php entry points (pages the user can navigate to). Also you shouldn't add user data directly to the query. Use prepared/parameterized queries. – JimL Jan 14 '16 at 21:56
  • Please use PHP's [built-in functions](http://jayblanchard.net/proper_password_hashing_with_PHP.html) to handle password security. If you're using a PHP version less than 5.5 you can use the `password_hash()` [compatibility pack](https://github.com/ircmaxell/password_compat). – Jay Blanchard Jan 14 '16 at 21:57
  • possible duplicate of [Load session_start() only if session does not exist?](http://stackoverflow.com/questions/10093264/load-session-start-only-if-session-does-not-exist) – Funk Forty Niner Jan 14 '16 at 21:58
  • Yes to all, a session has been started. Jay, I plan to add more security stuff once I get the script actually working in the first place. – GrumpyCrouton Jan 14 '16 at 21:58
  • [*hah,* knew it ^](http://stackoverflow.com/questions/34800479/issue-with-ajax-login-script#comment57344219_34800479) – Funk Forty Niner Jan 14 '16 at 21:59
  • @Fred-ii- this has nothing to do with sessions starting only if not existing, I already have code that handles that. – GrumpyCrouton Jan 14 '16 at 21:59
  • it's not in your "My form:". you have a new answer. – Funk Forty Niner Jan 14 '16 at 22:00
  • @Fred-ii- A session is started on the login page, I assure you. – GrumpyCrouton Jan 14 '16 at 22:01
  • instead of writing raw code why dnt you use redbeanphp – jewelhuq Jan 14 '16 at 22:03
  • 4
    I hate when people say, *"I'm not that far along..."* or, *"This site will not be public..."* or, *"It's only for school, so security doesn't matter..."*. If teachers and professors are not talking about security from day one, they're doing it wrong. They're teaching sloppy and dangerous coding practices which students will have to unlearn later. I also hate it when folks say, *"I'll add security later..."*. If you don't have time to do it right the first time, when will you find the time to add it later? – Jay Blanchard Jan 14 '16 at 22:04
  • Is the script running into the `if($exists == 1) {` condition? Maybe it's more than 1. – Tyr Jan 14 '16 at 22:05
  • spam what do you mean by spam? – jewelhuq Jan 14 '16 at 22:06
  • @JayBlanchard I hate when people assume things about other peoples work that they have no idea about, and contribute things that don't pertain to their question. Why would I add extra things for the code to process when it doesn't even work yet? I plan on adding security AS SOON AS, and NOT LATER than when I get the code to actually work. The code I have now is for testing. – GrumpyCrouton Jan 15 '16 at 13:46
  • @Tyr it cannot be more than one, because the username field is always unique. – GrumpyCrouton Jan 15 '16 at 13:47
  • I made no assumptions, *you* said you'd [add security later](http://stackoverflow.com/questions/34800479/issue-with-ajax-login-script?noredirect=1#comment57344296_34800479). The problem is that adding the security will change your code substantially and *might* even make your current problems disappear. Comments, such as the one that I made, do pertain to the the question. Are you running all of this on a web server? Or are you accessing the files locally? Where do you expect to see the session variable? – Jay Blanchard Jan 15 '16 at 13:49
  • @JayBlanchard It is in a Webserver. The session variable should save, and then be shown in a menu bar, along with unlocking the rest of the site. The only problem is that the session variable is never set. – GrumpyCrouton Jan 15 '16 at 13:56
  • 1
    Actually, and in agreement with the answer below, the session variable is set by the PHP you called....you're just not seeing it in the current page because you would have to reload the current page after the AJAX succeeds to see the session variable. – Jay Blanchard Jan 15 '16 at 13:58
  • @JayBlanchard I'd have to reload the current page? Or another page with sessions enabled? Because I already do that. It also did not work when reloading the same page. The redirect code is in my ajax code snippet in my question. – GrumpyCrouton Jan 15 '16 at 13:59
  • If you want to use a redirect then why use AJAX? – Jay Blanchard Jan 15 '16 at 14:00
  • @JayBlanchard Simple. The page should only redirect if login was successful. NOT when form submitted, NOT when login details are wrong. Also, I will be using a lot of ajax throughout this project, and thought this would be a good place to start learning. – GrumpyCrouton Jan 15 '16 at 14:02
  • Then you will have to call `window.location.replace(""new_url");` in the success function of the AJAX as you'll be redirecting from the page that you're in to the new page having a `session_start()` right after the opening PHP tags. – Jay Blanchard Jan 15 '16 at 14:04
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/100774/discussion-between-grumpy-and-jay-blanchard). – GrumpyCrouton Jan 15 '16 at 14:09
  • login.html ->AJAX(request)->login.php->AJAX(response)->login.html->(redirect to)index.php – Jay Blanchard Jan 15 '16 at 14:09
  • I am not where I can chat at the moment. – Jay Blanchard Jan 15 '16 at 14:09
  • @JayBlanchard I didn't mean to do that. That's not working either. Ugh, I really want to learn how this works but I could never really wrap my head around javascript much in the first place – GrumpyCrouton Jan 15 '16 at 14:11
  • JavaScript isn't much different than any other language, but its behavior is a game changer. Setup a very simple form set where you send a true or a false. Have the PHP echo back what you send. If you get a true back, redirect. If not, don't. [Read this.](http://jayblanchard.net/basics_of_jquery_ajax.html) – Jay Blanchard Jan 15 '16 at 14:13
  • @JayBlanchard How do I make it echo back the bool? – GrumpyCrouton Jan 15 '16 at 14:15
  • Send as text. I have to run off to a meeting. I'll write up a complete example, using your code, when I come back. – Jay Blanchard Jan 15 '16 at 14:17
  • @JayBlanchard Okay, I will keep trying, thank you very much. – GrumpyCrouton Jan 15 '16 at 14:17

4 Answers4

2

I was able to get it working the way I wanted it to.

Form:

<div id="box">
            <div class="row">
                <div class="col-sm-6 col-sm-offset-3 form-box">
                    <div class="form-top">
                        <div class="form-top-left">
                            <h3>Log-in</h3>
                            <span id="error" class="error"></span>
                        </div>
                        <div class="form-top-right">
                            <i class="fa fa-key"></i>
                        </div>
                    </div>
                    <div id="box" class="form-bottom">
                        <form class="login-form" action="" method="post">
                            <div class="form-group">
                                <label class="sr-only" for="username">Username</label>
                                <input type="text" name="username" placeholder="Username..." class="form-username form-control" id="username">
                            </div>
                            <div class="form-group">
                                <label class="sr-only" for="password">Password</label>
                                <input type="password" name="password" placeholder="Password..." class="form-password form-control" id="password">
                            </div>
                            <input type="submit" id="login" class="btn" style="width:100%;background-color:lightblue;" value="Log In" id="login"/>
                        </form>
                    </div>
                </div>
            </div>
        </div>

AJAX Code:

<script src="js/jquery.min.js"></script>
<script src="js/jquery.ui.shake.js"></script>
        <script>
            $(document).ready(function() {

            $('#login').click(function()
            {
            var username=$("#username").val();
            var password=$("#password").val();
            var dataString = 'username='+username+'&password='+password;
            if($.trim(username).length>0 && $.trim(password).length>0)
            {


            $.ajax({
            type: "POST",
            url: "ajax/login.php",
            data: dataString,
            cache: false,
            beforeSend: function(){ $("#login").val('Connecting...');},
            success: function(data){
            if(data)
            {
            window.setTimeout(function () {
                location.href = "index.php";
            }, 3000);
            }
            else
            {
             $('#box').shake();
             $("#login").val('Login')
             $("#error").html("<span style='color:#cc0000'>Error:</span> Invalid username and password. ");
            }
            }
            });

            }
            return false;
            });


            });
        </script>

PHP (ajax/login.php):

<?php
include("../static/config.php");
session_start();
if(isSet($_POST['username']) && isSet($_POST['password']))
{
// username and password sent from Form
$username=mysqli_real_escape_string($con,$_POST['username']); 
$password=mysqli_real_escape_string($con,$_POST['password']); 

$result=mysqli_query($con,"SELECT Name FROM techs WHERE Username='$username' and Password='$password'");
$count=mysqli_num_rows($result);

$row=mysqli_fetch_array($result,MYSQLI_ASSOC);
// If result matched $myusername and $mypassword, table row must be 1 row
if($count==1)
{
$_SESSION['Name']=$row['Name'];
echo $row['Name'];
}

}
?>
GrumpyCrouton
  • 8,171
  • 5
  • 29
  • 65
  • Good! I was just writing up my answer, but since you figured out something that works I'll discard it and move along! – Jay Blanchard Jan 15 '16 at 15:40
  • Solving it yourself, and bothering to pass your solution on as an answer, thats worth an Upvote. – RiggsFolly Jan 15 '16 at 15:43
  • 1
    A couple of things that jump out at me! A bit if sensible code indentation would make the code easier to read and more importantly debug. More importantly, you only pass a reply back to the javascript IF you find the Uid/Pwd in the database. It would be better to pass back a reply for both **success and failure** so the JS can act accordingly – RiggsFolly Jan 15 '16 at 15:47
  • @RiggsFolly It already acts in that way, if the data input is invalid information, it "shakes" the form, and says invalid username or password. – GrumpyCrouton Jan 15 '16 at 16:04
  • But you dont actually `echo` anything back to the javascript if `$count == 0` – RiggsFolly Jan 15 '16 at 16:11
  • @RiggsFolly Exactly, which shows the code that there is no users with that user and pass combo. Therefore, it can confidently reply that the account info is false. – GrumpyCrouton Jan 15 '16 at 16:15
1

Since you've stated you're very new to Ajax, you start off pretty well. There are however a couple of things to know how this works.

You want to avoid a page refresh, yet you don't print out any responses because you're not returning anything in the ajax request. You instead set a session variable which will show up at the next page request (so a refresh)

$.ajax({ 
    type: 'POST', 
    url: 'ajax/login.php', 
    data: { username:  $("#username").val(), password:  $("#password").val() }, 
    success: function (data) { 
        $('.form-bottom').html(data); // here we replace the form with output of the ajax/login.php response.
    }
});

And for the PHP side of things:

    $sql = "SELECT Name FROM techs WHERE Username='$username' AND Password='$password'";
    if(($result = mysqli_query($con, $sql)) != false){ // always verify if your query ran successfully.
        if(mysqli_num_rows($result)){ // or compare with == 1, but assuming a username is unique it can only be 1 so it equals to true.
            echo mysqli_fetch_assoc($result)['name']; // index, columns, etc should always be lower cased to avoid confusion.
            // Obviously you can store it in a session
            // But for now just output the data so we can use it as our response.
            // json is very usefull with sending large amounts of data.
        }
    }

The idea of Ajax is that you can request an update, but you need to update your page with javascript manually in order to make it work.

Xorifelse
  • 7,708
  • 1
  • 24
  • 37
  • Uh.....whut? Index should always be lowercase? Since it is "Name" in the query it should be "Name" in the return. If not, your function will fail. You also do not do any error checking on your query. – Jay Blanchard Jan 14 '16 at 22:21
  • Yeah... updated the comment of that line, meant to say that database colomns, array indexes, etc.. should just be lower case. For example, running the exact same code on a Linux system (which is case sensitive) could break it compared with Windows. – Xorifelse Jan 14 '16 at 22:27
  • Hmmmm, that is a nugget of wisdom I've not heard in my many, *many* years of programming. A quick search of the interwebs doesn't reveal that little tidbit either. *Just sayin'*. – Jay Blanchard Jan 14 '16 at 22:29
  • Thanks for the kind words, I can't even remember when I picked it up but to make it easier for everybody here is some information about the subject http://stackoverflow.com/questions/2009005/are-column-and-table-name-case-sensitive-in-mysql – Xorifelse Jan 14 '16 at 22:39
  • That wasn't the nugget I was talking about. – Jay Blanchard Jan 15 '16 at 01:11
  • @Xorifelse - My plan was to refresh the page if the login was successful. I am still not really understanding how to use the data submitted to check if it was a successful login, and then refresh. I just didn't want the page to refresh on clicking the login button, but only when it was successful. Ideally I would like, `if login = success do redirect to index else display error message` – GrumpyCrouton Jan 15 '16 at 13:51
  • Instead of doing a redirect you can perform a reload of the current page when the AJAX is successful by calling `window.location.reload();` – Jay Blanchard Jan 15 '16 at 13:57
  • @JayBlanchard I would rather it be a redirect, so that was it can go to the correct page, as mentioned above, the index. – GrumpyCrouton Jan 15 '16 at 13:58
  • @Grumpy the most important part here is to use `data: { username: $("#username").val(), password: $("#password").val() },` then you can implement your `window.location.reload();` as you have it now. This answer worked for me when I tested it last night. – Funk Forty Niner Jan 15 '16 at 14:09
  • @Xorifelse this was the nugget: *"Index should always be lowercase."* – Jay Blanchard Jan 15 '16 at 14:15
0

I think you forget to start the session.So start the session at the top of your script. Hope it will help.

 session_start();

    include('./static/config.php');

    if(isset($_POST)) {


        $username = mysqli_real_escape_string($con, $_POST['username']);
        $password = mysqli_real_escape_string($con, $_POST['password']);

        $sql = "SELECT Name FROM techs WHERE Username='$username' AND Password='$password'";
        $result = mysqli_query($con, $sql);
        $exists = mysqli_num_rows($result);

        if($exists == 1) {
        $row = mysqli_fetch_assoc($result);
            $_SESSION['Name'] = $row['Name'];
        }

    }
jewelhuq
  • 1,154
  • 13
  • 19
0

3 things you could try:

  1. On the page where you are trying to set the session variable you would have to use proper php opening tags like <?php
  2. Second thing is that you would have to put a value in your session like $_SESSION['hello'] = 'hello';
  3. Third thing, on every page where you handle your session you would have to call <?php session_start(); ?> for it to work.

Goodluck!

chris85
  • 23,591
  • 7
  • 30
  • 47
Frank W.
  • 759
  • 2
  • 13
  • 32
  • 1. I'm pretty sure shorthand is fine for this. 2. I'm already putting a variable in my $_SESSION? That's the point 3. Sessions are already being called on every page. – GrumpyCrouton Jan 15 '16 at 13:53