Ajax login only working half the time?

Ended up doing this. I don’t like the idea of having to set the variables twice (one for js on/off) so suggestions appreciated

  if($isAjax)
  {
    $_SESSION['test']="holyeffpleasework";
    $result = [ 'success' => $isValidLogin ];
    header('Content-Type: application/json');
    exit(json_encode($result));
  }
  if($isValidLogin)
  {
    $_SESSION['test']="holyeffpleasework";
    header('Location: http://www.codefundamentals.com/cadeui/dashboard');
  }
  else
  {
    header('Location: http://www.codefundamentals.com/cadeui/login');
  }

Alright I notice that hwen I submit pages with invalid data (JS on) I still get session variables set. That’s because $isAjax only sets for the ajax method being sent.

  $isValidLogin = $login->checkCredentials($email, $password);echo $isValidLogin;
  $isAjax = !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';

  if($isAjax)
  {
    $_SESSION['test']="ajaxloginholyfuck";
    $result = [ 'success' => $isValidLogin ];
    header('Content-Type: application/json');
    exit(json_encode($result));
  }
  if($isValidLogin)
  {
    $_SESSION['test']="validloginholyfuck";
    header('Location: http://www.codefundamentals.com/cadeui/dashboard');
  }
  else
  {
    header('Location: http://www.codefundamentals.com/cadeui/login');
  }

I tried switching the if $isAjax to include && $isValidCredentials but I got an error in my JS console. Invalid < character from my login.php (login page.)

Can anyone shed light?
@fretburner

I feel like my checkCredentials is returning something other than a boolean.

<?php
class LoginRepository
{
  private $pdo;
  
  public function __construct(PDO $pdo)
  {
    $this->pdo = $pdo;
  }
  public function checkCredentials($username, $password)
  {
    $userQuery = $this->pdo->prepare('SELECT * FROM Users WHERE username = :username');
    $userQuery->execute(array(':username' => $username));

    // If no user by that name, then check credentials failed
    if ($userQuery->rowCount() === 0)
      return false;

    // Verify password
    $userDetails = $userQuery->fetch(PDO::FETCH_ASSOC);
    return password_verify($password, $userDetails['password']);
  }
}
?>

Echoing it out should only give true/false right? Returning it and using it in if() seems to generate errors. That shouldn’t be happening.

JS off + logging in wrong/right is all perfect
JS on + logging in right is perfect
JS on + logging in wrong is what i notice fails / sets the session variable incorrectly.

Fixed by doing $.post() to a set-sessions.php (in the success) and set sessions there. Seems to be working but I’m not sure whether that’s the best way?

Hi Ryan,

What is it you’re trying to achieve with the session variables? Are you trying to set a ‘logged-in’ var, so you can check if the current user is authenticated on different pages?

Yes - along with a few other session variables.

I did get it working, It’s 100% working. I just don’t know whether I needed to .post() to a separate PHP set-sessions.php and set sessions there.

No that’s not necessary, any session vars you set from the processLogin.php script will be available to new Ajax and full page requests. If you need to make some data available to the login form page and you’re using Ajax to login, just pass the data back in the response from the server.

It would make sense to set your session tracking vars from within your login class - that way you can assure they always get set, and you don’t need to complicate the code in processLogin.php

The problem was if you look at post #24, is that isAjax only is true if hte method is AJAX (js on). That then exits the results back to the login.js file to process. If I set the test session variable there like I did, it still gets set on invalid data because it STILL recognizes the method is ajax and it doesnt check for valid data.

I tried doing $isAjax && $isValidLogin but I got an error

Not sure how to do this.

The login class only returns password_verify (boolean). Should I check if that’s true and then set session variables? THen return it?

Yes, that’s one way, something like this:

if ($isValidLogin) {
	// Set your session vars
	$_SESSION['email'] = $email;
}

if ($isAjax) {
	header('Content-Type: application/json');
	exit( json_encode( [ 'success' => $isValidLogin ] ) );
}

if ($isValidLogin) {
	header('Location: http://www.example.com/admin.php');
} else {
	header('Location: http://www.example.com/login.php?status=failed');
}

The other alternative is to modify your checkCredentials method:

public function checkCredentials($username, $password)
{
    // ...
    $userDetails = $userQuery->fetch(PDO::FETCH_ASSOC);
    $isVerified = password_verify($password, $userDetails['password']);

    if ($isVerified) {
            session_start();
            $_SESSION['currentUser'] = $userDetails;
        }

        return $isVerified;
}

Doing it here is a little neater, IMO, and will ensure the session vars get set even if you call the method from somewhere else in your app.

I ended up doing this just before you posted

  public function checkCredentials($username, $password)
  {
    $userQuery = $this->pdo->prepare('SELECT * FROM Users WHERE username = :username');
    $userQuery->execute(array(':username' => $username));

    // If no user by that name, then check credentials failed
    if ($userQuery->rowCount()===0)
      return false;

    $userDetails = $userQuery->fetch(PDO::FETCH_ASSOC);
    if(password_verify($password, $userDetails['password']))
    {
      $this->setSessions();
      return true;
    }
    else
      return false;
  }
  private function setSessions()
  {
    $_SESSION['test']="setsessionsfunctionholyfuck";
  }

I’ll modify that to send the database details as parameters etc, but it’s there.
I removed the .post() call and cleaned out processLogin. I did a separate function since I imagine having to set quite a few session variables due to the foreseeable size of this application.

  if($isAjax)
  {
    $result = [ 'success' => $isValidLogin ];
    header('Content-Type: application/json');
    exit(json_encode($result));
  }
  if($isValidLogin)
    header('Location: http://www.codefundamentals.com/cadeui/dashboard');
  else
    header('Location: http://www.codefundamentals.com/cadeui/login');

All fixed, thank you.

Onto delaying login attempts by a few seconds and maxing out attempts :wink: . This is fun. Certainly nice to have a break from drowning in HTML/CSS all day.

1 Like

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.