3

I use these packages with these versions to create tokens for user login, but I encounter this error when creating tokens:

composer.json

"require": {
    "php": "^7.3|^8.0",
    "fideloper/proxy": "^4.4",
    "fruitcake/laravel-cors": "^2.0",
    "guzzlehttp/guzzle": "^7.0.1",
    "laravel/framework": "^8.12",
    "laravel/passport": "^10.1.3",
    "laravel/tinker": "^2.5",
    "laravel/ui": "^3.2",
    "laravelcollective/html": "^6.2",
    "lcobucci/jwt": "3.4.5",
    "spatie/laravel-permission": "^4.0"
},
"require-dev": {
    "barryvdh/laravel-ide-helper": "^2.9",
    "facade/ignition": "^2.5",
    "fakerphp/faker": "^1.9.1",
    "laravel/sail": "^1.0.1",
    "mockery/mockery": "^1.4.2",
    "nunomaduro/collision": "^5.0",
    "phpunit/phpunit": "^9.3.3"
}

routes/api.php

Route::post('login', [ApiLoginController::class, 'login']);

ApiLoginController.php

public function login(Request $request)
{
    $this->validateLogin($request);

    $user = User::where($this->username, $request->get('username'))
        ->first();

    if (Auth::attempt([$this->username => $request->get('username'), 'password' => $request->get('password')])) {

        if ($user->status != 'active') {
            $msg = 'Account is not active';

            return $this->customError($msg);
        }

        $success['token'] = $user->createToken('Personal Access Client')->accessToken;
        $success['name'] = $user->name;
        $success['phone'] = $user->phone;
        $success['email'] = $user->email;

        $user->password = null;
        $user->save();

        return $this->success($success, "Login completed successfully");

    }

    //delete user password
    if ($user){
        $user->password = null;
        $user->save();
    }

    $msg = 'The information entered does not match our information';

    return $this->customError($msg);
}

Postman Response

{
"message": "Method Laravel\\Passport\\Bridge\\AccessToken::__toString() must not throw an exception, caught Lcobucci\\JWT\\Signer\\InvalidKeyProvided: It was not possible to parse your key, reason: error:0908F070:PEM routines:get_header_and_data:short header",
"exception": "Symfony\\Component\\ErrorHandler\\Error\\FatalError",
"file": "F:\\xampp\\htdocs\\Diapad-BackEnd\\vendor\\league\\oauth2-server\\src\\ResponseTypes\\BearerTokenResponse.php",
"line": 0,
"trace": []
}

This process works without a token line. Even a token is created but not returned as a string. I lowered or even upgraded my package version several times, but it didn't work.

Negar Javadzadeh
  • 325
  • 7
  • 11
  • 1
    Seems like you are a bit behind on your PHP version. Throwing exceptions from `__toString()` is allowed since PHP 7.4 – Repox Apr 14 '21 at 06:51
  • 2
    take a look here https://blog.pusher.com/laravel-jwt/ – Zia Yamin Apr 14 '21 at 06:54
  • @Repox That may be true but I don't think it's normal for `__toString` to throw an exception. One could call it ... an exceptional event. – apokryfos Apr 14 '21 at 07:55
  • @apokryfos Well, since there was an [RFC](https://wiki.php.net/rfc/tostring_exceptions) for allowing this, with an unanimously accept, I would assume that throwing exceptions in `__toString()` was _impossible_, not _'not normal', but a desired need that has been implemented. Regardless, the behaviour is accepted in PHP 7.4 and later. – Repox Apr 14 '21 at 08:46
  • 1
    @NegarJavadzadeh That's another error. That's because your implementation throws an Exception that you didn't catch. You should `try { } catch(\Lcobucci\\JWT\\Signer\\InvalidKeyProvided $e) { handle_the_exception_message($e->getMessage()); }` – Repox Apr 14 '21 at 08:53
  • @Repox first of all it was not impossible to throw an exception in a `__toString` method. PHP just did not handle this the same way it handled exceptions thrown elsewhere. Secondly, the solution to this question is not upgrading PHP to support exceptions in `__toString` it's **to stop the exceptions from being thrown in the first place** – apokryfos Apr 14 '21 at 08:53
  • Yes, thank you very much. The problem was solved @Repox – Negar Javadzadeh Apr 14 '21 at 08:55
  • @apokryfos You can't catch exceptions if they are not allowed to be thrown. Clearly, the `lcobucci/jwt` package implemented a `throw` in a `__toString()` which is possible from PHP .7.4, as the RFC suggested. Saying that "upgrading PHP is not the solution" is a terrible mindset for a number of reasons, but mainly you should accept that when using dependencies that depend on a minimum version of a platform, the only solution is to follow through and not ask the library provider to stop using implemtented features. – Repox Apr 14 '21 at 08:57
  • @Repox Passport 10.1 does not have the requirements you're mentioning. It requires `"lcobucci/jwt": "^3.4|^4.0"` and 3.4 does satisfy PHP version constraints lower than 7.4. And I am saying that upgrading PHP is not an answer to this question. Solving the reason as to why the exception was thrown is the answer to this question – apokryfos Apr 14 '21 at 08:58
  • @apokryfos Yes, downgrading software seems like a ridiculous approach, honestly. I'm not going to waste my time debating obviously foolishness like not upgrading when it's actually possible. You do yours, but don't act like it's bad advice to encourage people to be up to date with their software and dependencies. – Repox Apr 14 '21 at 09:02
  • @Repox (a) **no one is suggesting to downgrade** PHP version. I'm saying that PHP 7.3 is supported and upgrading to PHP 7.4 is not the solution to this problem. (b) it's not always possible to upgrade the PHP version. Maybe OP can but not everyone who encounters this problem has that option (even so as I said, it's not the solution to the problem). – apokryfos Apr 14 '21 at 09:36

1 Answers1

1

You're probably on a PHP version prior to 7.4.

Throwing exceptions in the __toString() method was allowed by this RFC which was accepted for PHP 7.4

The laravel/passport package relies on lcobucci/jwt as well as the required league/oauth2-server also does.

lcobucci/jwt has a minimum of PHP 7.4 dependency written which your composer install or composer update should have caught at some point unless you haven't installed them yourself or used composer with the --ignore-platform-reqs flag.

Repox
  • 15,015
  • 8
  • 54
  • 79