User login from frontend with exception - The passwords do not match

I am able to login the user from the frontend successfully, when the password matches the user password with the code below. But when the password is not matching instead of the else: invalid username or password I get an exception (below).

I also tried to validate (below) before with validatePassword(), but here happens the same, when the password is correct everything is fine, is the password not correct I get an exception instead of bool() true/false.

Any idea?

first approach:

<?php

if(isset($_POST['login'])){

        if($username = $_POST['email'] and $password = $_POST['password']) {

            $user = $kirby->user($username);
        
            if($user->login($password)):
            
                go('account');

            else:

                echo 'invalid username or password';

            endif;
        
        }
    }

approach instead with validatePassword():

<?php

if(isset($_POST['login'])){

    if($username = $_POST['email'] and $password = $_POST['password']) {

        $user = $kirby->user($username);
        
        if($user->validatePassword($password, $user->password()) == true):

            echo 'ok';

        else:

            echo 'nok';

        endif;
    }
}

exception:

/Users/agloeckner/Library/Mobile Documents/com~apple~CloudDocs/web/whosgotsoul.com/kirby/src/Cms/User.php
     *
     * @param string $password
     * @return bool
     *
     * @throws \Kirby\Exception\NotFoundException If the user has no password
     * @throws \Kirby\Exception\InvalidArgumentException If the entered password is not valid
     * @throws \Kirby\Exception\InvalidArgumentException If the entered password does not match the user password
     */
    public function validatePassword(string $password = null): bool
    {
        if (empty($this->password()) === true) {
            throw new NotFoundException(['key' => 'user.password.undefined']);
        }
 
        if (Str::length($password) < 8) {
            throw new InvalidArgumentException(['key' => 'user.password.invalid']);
        }
 
        if (password_verify($password, $this->password()) !== true) {
            throw new InvalidArgumentException(['key' => 'user.password.notSame']);
        }
 
        return true;
    }
}

If you wrap your logic in a try/catch block, you can react on Exceptions and echo whatever you want instead, see: https://getkirby.com/docs/cookbook/security/access-restriction#the-login-template__the-controller

1 Like

Perfect, thanks for the hint. That’s my logic.

<?php

if(isset($_POST['login'])){

    if($username = $_POST['email'] and $password = $_POST['password']) {

        $user = $kirby->user($username);

        try {
          $user->login(get('password'));

          go('account');

        } catch (Exception $e) {

        echo 'Invalid username or password.';

        }
          
    }

} ?>