Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

PHP PHP User Authentication Adding Authentication to Your Application User Profile

Jonathan Grieve
MOD
Jonathan Grieve
Treehouse Moderator 90,705 Points

Password updater function will not update

I've almost finished the stage. I did have another problem in another thread but I managed to bypass that using Git.

So everything now works except for the password update. I've traced back the error as far as I can but I've no doubt at the query I'm using is the right one.

The returned error is

"(Some error happened! If this happens again please log out and back in.)"

Which means that for whatever reason the user is not being properly loaded but I don't see how?

https://bitbucket.org/jg_digitalMedia/php_auth/src/master/

functions.php
function findUserByAccessToken() {
    global $db;

    try {
        $userId = decode_jwt('sub');
    } catch(\Exception $e) {
        throw $e;
    }

    try {
        $query = "SELECT * FROM users WHERE id = :userId";
        $stmt = $db->prepare($query);
        $stmt->bindParam(':userId', $userId);
        $stmt->execute();
        return $stmt->fetch(PDO::FETCH_ASSOC);
    } catch(\Exception $e) {    
        throw $e;
    }
}

function createUser($email, $password) {
    global $db;

    try {
        $query = 'INSERT INTO users (email, password, role_id) VALUES (:email, :password, 2)';
        $stmt = $db->prepare($query);
        $stmt->bindParam(':email', $email);
        $stmt->bindParam(':password', $password);
        $stmt->execute();
        return findUserByEmail($email);

    } catch (\Exception $e) {
        throw $e;
    }
}

function updatePassword($password, $userId) {
    global $db;

    try {
        $query = 'UPDATE users SET password=:password WHERE id = :userId';
        $stmt = $db->prepare($query);
        $stmt->bindParam(':password', $password);
        $stmt->bindParam(':userId', $userId);
        $stmt->execute();

    } catch (\Exception $e) {
       return false;
    }

    return true;
}
changePassword.php
<?php

require __DIR__ . '/../inc/bootstrap.php';
requireAuth();

$currentPassword = request()->get('current_password');
$newPassword = request()->get('password');
$confirmPassword = request()->get('confirm_password');

if($newPassword != $confirmPassword) {
    $session->getFlashBag()->add('error', 'New passwords do not match, please try again.');
    redirect('/php_auth/account.php');

}

$user = findUserByAccessToken();

if(empty($user)) {
    $session->getFlashBag()->add('error', 'Some error happened! If this happens again please log out and back in.');
    redirect('/php_auth/account.php');
}

if(!password_verify($currentPassword, $user['password'])) {
    $session->getFlashBag()->add('error', 'Current Password is incorrect. Please try again');
    redirect('/php_auth/account.php');
}

$updated = updatePassword(password_hash($newPassword, PASSWORD_DEFAULT), $user['id']);

if (!$updated) {
    $session->getFlashBag()->add('error', 'Could not update password. Try again!');
    redirect('/php_auth/account.php');
}


$session->getFlashBag()->add('success', 'Success! You have updated your password!');
redirect('/php_auth/account.php');

2 Answers

Aleksandr Antropov
Aleksandr Antropov
6,458 Points

Hello, I had the same problem as you. I know it's late, but my solution may help others. So I was having this error message, because decodeJwt() returned a string - '{userId}' literally. Instead of a 'userId' value. It was a typo in the 'doLogin.php' file. When creating jwt 'sub' key in 'doLogin.php' assign value "{$userId}" instead of "{userId}".

Jonathan Grieve
Jonathan Grieve
Treehouse Moderator 90,705 Points

Hi Alexsandr,

I want to thank you for taking the time to respond to this. I've got it working now!

Interestingly it wasn't your solution itself that did it for me, although it was certainly the catalyst. I will your mark your post as best answer though as it is bound to help somebody.

I was actually using the 'sub' key correctly as you described in your post. What seems to have done the trick is I'm returning return $jwt->{$prop}; in the decode_jwt* function instead of return $jwt->{prop}; as I was initially. Now, before I did this the sub key was showing up as an empty string. Suddenly I noticed the number 1 was showing up in the sub key which means the user was showing up as an administrator. And while I'll verify the password change later in my SQLite Browser I know this has worked because the file shows up as modified in Git.

The only thing is I now can't replicate the empty string in the JWT tab of Chrome DevTools but that's okay. There's a lot of little things about tech I still can't wrap my head around. :)

Aleksandr Antropov
Aleksandr Antropov
6,458 Points

I might have been hard to understand. I didn't think you had the same problem, but sort of a kind. Glad it helped, good luck :)