Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

PHP PHP User Authentication Adding Authentication to Your Application User Profile

Jonathan Grieve
MOD
Jonathan Grieve
Treehouse Moderator 91,253 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 91,253 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 :)