2

I have a login form which trigger an ajax to a php page which set the session. If the return of the ajax is 'success' it reload the page. The first time the session variables are there. But if I reload the same page again by pressing F5, the session is gone.

Login form page

<?php 
  session_start();
  include 'connect.php';
  if(isset($_SESSION['id'])) {
    $id = intval($_SESSION['id']);
    $result = $conn->query("SELECT * FROM users WHERE id = $id LIMIT 1");
    $user   = $result->fetch_assoc();
    $ids    = explode(',', $user['ids']);
    $tiers  = explode(',', $user['tiers']);
    $ranks  = explode(',', $user['ranks']);
    $levels = explode(',', $user['levels']);
    $sigs   = explode(',', $user['sigs']);
  }
?>
<form>
  <div class="login">
    <div><span>Username / E-mail:</span><input type="text" name="login"/></div>
    <div><span>Password:</span><input type="password" name="password"/></div>
    <div><button type="button" class="login">Login</button><button type="button" class="cancel">Cancel</button></div>
  </div>
</form>

javascript

document.querySelector('button.login').addEventListener('click', function() {
  var form = document.forms[0];
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if(this.readyState == 4) {
      if(this.responseText == 'success') location.reload();
      else alert(this.responseText);
    }
  }
  xhttp.open('POST', 'ajax.php', true);
  xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  request = 'login=' + form.login.value + '&password=' + form.password.value + '&action=login';
  xhttp.send(request);
});

ajax.php

<?php
  session_start();
  include 'connect.php';
  extract($_POST);

  if($action == 'login') {
    $stmt = $conn->prepare('SELECT id FROM users WHERE (name = ? OR email = ?) AND password = ? LIMIT 1');
    $stmt->bind_param('sss', $login, $login, $password);
    $stmt->bind_result($id);
    $stmt->execute();
    $stmt->store_result();
    if($stmt->num_rows < 1) die('Wrong username/email or password');
    $user = $stmt->fetch();
    $_SESSION['id'] = $id;
    echo 'success';

  }
  • Check your browser dev tools, and monitor the existence and setting/changing of the default PHPSESSID cookie (if you have it named something else, look at that named cookie). – IncredibleHat Mar 09 '18 at 16:21
  • Can you try it without `xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');`? – Orry Mar 09 '18 at 16:22
  • 4
    **Warning** Do not use [extract()](http://php.net/manual/en/function.extract.php) on untrusted data, like user input – CD001 Mar 09 '18 at 16:23
  • 1
    Side note: You should look into using the `password_hash()` and `password_verify()` pair of functions to deal with user passwords, instead of storing them as plain text in the db. – IncredibleHat Mar 09 '18 at 16:24
  • `$stmt->bind_result($id);` should be *after* `$stmt->execute();` ... and you probably don't want both `bind_result()` and `store_result()` – CD001 Mar 09 '18 at 16:28
  • 1
    *"and you probably don't want both bind_result() and store_result()"* - @CD001 it is required. I.e.: execute/store/bind. – Funk Forty Niner Mar 09 '18 at 16:39
  • 1
    @FunkFortyNiner ... wouldn't you just execute -> bind -> fetch? – CD001 Mar 09 '18 at 16:40
  • @CD001 no because storing the results ensures that it is doing just that, "storing". See [one of my answers](https://stackoverflow.com/a/22253579/1415724). If we were to take out the storing, it would fail. This is especially true for a prepared statement method. – Funk Forty Niner Mar 09 '18 at 16:45
  • PHPSESSID is there and has the same value after I do login and the session is set and after I reload the page and the session is gone. without the xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); the login stops working. textResponse returns null. What are the potential threats of using extract there even if I use prepared statements? Doesn't it works the same either way with bind_result() before or after execute()? – Deixadilson Mar 09 '18 at 16:47
  • @CD001 One problem they're doing here, is trying to check if a row exists *before* they "fetched" their results. Compare what they have now with that link I gave you for one of my answers. – Funk Forty Niner Mar 09 '18 at 16:48
  • @FunkFortyNiner - okelly doke, I stand corrected :) Haven't used `mysqli_*` for a while - tbh I've barely touched anything this close to the db since they foisted Magento onto us at work :\ – CD001 Mar 09 '18 at 16:50
  • @CD001 :-) *cheers*. – Funk Forty Niner Mar 09 '18 at 16:51
  • 1
    @FunkFortyNiner you got me pondering with that *it is required* comment with `store_result` ..... you *can* skip `store_result` if all you do is execute -> bind -> fetch (as @CD001 asked) (at least this is true in my work environs without mysqlnd). ***However***, if one *also* wants to use `num_rows` like the question-asker has, then `store_result` is *definitely required* (or it always returns zero). I am only clarifying the difference in when it is required or not. Don't hurt me. – IncredibleHat Mar 09 '18 at 17:42
  • @IncredibleHat Thanks man, I appreciate it :-) Edit: Errr.. you are a "man" right? heh... just in case. – Funk Forty Niner Mar 09 '18 at 17:43
  • 1
    @IncredibleHat addendum to my above. About your *"However, if one also wants to use num_rows like the question-asker has, then store_result is definitely required (or it always returns zero)"* - is what I meant when I responded to CD001. – Funk Forty Niner Mar 09 '18 at 17:46
  • @FunkFortyNiner Ok... I kept re-reading it, and then your own answer, and couldn't be sure... so I was just trying to clarify. You even made me go and make some test scripts and test the different outcomes of using it with and without other methods dagnabbit ;) Had me all second guessing myself lol. – IncredibleHat Mar 09 '18 at 17:48
  • 1
    @IncredibleHat I second guess myself at times also *lol!* - When in doubt, try it out. Hey, I think I just made a new slogan, *heh*, funny that. TBH, I haven't tried it the other way, so I'll be doing that sometime soon. Am I second guessing myself here? haha, I think I am but well worth the test. *Cheers* – Funk Forty Niner Mar 09 '18 at 17:50

0 Answers0