15

I use Laravel 6 passport grant password for my Vue backend.

When i send right credential to oauth/token it works and returns token, but when i send wrong (email/password) it returns 400 instead of 401 with this message.

    {
    "error": "invalid_grant",
    "error_description": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.",
    "hint": "",
    "message": "The provided authorization grant (e.g., authorization code, resource owner credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client."
}

I checked client_id and client_secret.

I tested with new installed Laravel + passport with out single line of code, Laravel 5.8 returns 401 without any problem but Laravel 6 returns 400 bad request.

Do you have any Idea?

Mojtaba Sayari
  • 475
  • 1
  • 5
  • 16

5 Answers5

14

Finally i found the problem, the problem is back to league/oauth2-server which that used by Laravel passport.

They changed response from 401 to 400 in version 8.

PR link

I changed my code in login section to this.

switch ($e->getCode()) {
    case 400:
    case 401:
        return response()->json('Your credentials are incorrect. Please try again', $e->getCode());
    break;
    default:
        return response()->json('Something went wrong on the server', $e->getCode());

}

Mojtaba Sayari
  • 475
  • 1
  • 5
  • 16
  • i switched in my own codes, "we usually don't change vendor files...", but if you want know where was the change vendor/league/oauth2-server/src/Grant/PasswordGrant.php line **107** `throw OAuthServerException::invalidGrant(); ` change to `throw OAuthServerException::invalidCredentials();` @azurecorn – Mojtaba Sayari Dec 12 '19 at 22:04
  • I'm facing the same issue. Do you know if Is this a known issue or a new way to throw exceptions? Your solution actually does not represent the real response since you won't be able to show "Hey! complete login data!" or "Hey! Your data is wrong!" – Luciano Feb 16 '20 at 05:49
  • seems it's new way, and it should be 400 regarding this document `https://tools.ietf.org/html/rfc6749#section-5.2`. If you want separate wrong credential with error, you can create token manually by validating username and password then `$user->createToken('tokenName')->accessToken` @Luciano – Mojtaba Sayari Feb 17 '20 at 08:28
  • 1
    Tha's correct @Mojtaba Sayari, confirmed by the creators in https://github.com/thephpleague/oauth2-server/issues/1093 Thanks for your possible solution BTW – Luciano Feb 23 '20 at 05:46
  • 1
    I sugest you use abort instead of response: `abort($response->status(), 'Your credentials are incorrect. Please try again')` – Caio Kawasaki Mar 04 '20 at 15:26
0

You can add the error handler on App\Exceptions\Handler

use League\OAuth2\Server\Exception\OAuthServerException;
class Handler extends ExceptionHandler
{
    public function render($request, Exception $exception)
    {
        if (get_class($exception) === OAuthServerException::class) {
            response()->json(['message' => $exception->getMessage()], 401);
        }
    }
}
Natan Augusto
  • 360
  • 5
  • 5
0

I had to use the following in laravel 7.x to convert the 400 level error to 401 in app/Exceptions/Handler.php

NB: check the OAuthServerException::class type

/**
 * Render an exception into an HTTP response.
 *
 * @param \Illuminate\Http\Request $request
 * @param \Exception $exception
 * @return \Illuminate\Http\Response
 */
public function render($request, Throwable $exception)
{
    if (get_class($exception) === \Laravel\Passport\Exceptions\OAuthServerException::class) {
        return response(['message' => $exception->getMessage()], 401);
    }

    return parent::render($request, $exception);
}
Shobi
  • 10,374
  • 6
  • 46
  • 82
0

Update UserFactory password (use Hash::make() not bcrypt)

TohidHabiby
  • 186
  • 4
0

try this:

php artisan passport:keys --force
php artisan passport:client --password

then edit your .env

PASSPORT_CLIENT_ID="Client ID"
PASSPORT_CLIENT_SECRET="Client secret"
风声猎猎
  • 1,065
  • 1
  • 7
  • 9