I followed the exact steps mentioned in the Laracast: What's New in Laravel 5.3: Laravel Passport and API Authentication (Passport) to implement API Authentication using Oauth2.
consumer/routes/web.php
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => '3',
'redirect_uri' => 'http://consumer.dev/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://passport.dev/oauth/authorize?'.$query);
});
Route::get('/callback', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://passport.dev/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '3',
'client_secret' => '3TfJGj4rrvOQvjZkI8dDqx78ouH99F2DuIMKHoKH',
'redirect_uri' => 'http://consumer.dev/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});
When I try to access http://consumer.dev/redirect, I get this error:
ClientException in RequestException.php line 111:
Client error: `POST http://passport.dev/oauth/token` resulted in a `401 Unauthorized` response:
{"error":"invalid_client","message":"Client authentication failed"}
How to resolve this? Thank you for your help!
@taitrongnguyen107 In your oauth_clients table, do the values you have above exist exactly as you have them in your database?
id - 3
secret - 3TfJGj4rrvOQvjZkI8dDqx78ouH99F2DuIMKHoKH
redirect - http://consumer.dev/callback
If it doesn't exist exactly like that in the database for passport.dev then it will throw the invalid_client error. Please be sure to check that and we will see if any further investigation is needed.
@craigpaul Everything is exact but it still appear this error. I checked. Please help me. Thank you.
@taitrongnguyen107 Ok, so I just went through the instructions and everything worked out perfectly. That leads me to believe it might be the version of Passport you have installed or the environment in which you are working. Before I post the code and data I had available for this test, I am using Homestead and have the latest version of Passport installed at the time of writing (1.0.17). So this was the process I followed, perhaps it might show something you may have missed.
I set up two different new Laravel projects and they can be accessed at provider.dev and consumer.dev. They have two separate databases, provider and consumer. In the provider project, I installed Passport with composer require laravel/passport. The next step was to add the service provider and run migrate the database. After that I ran the php artisan passport:install command to generate the private keys and two entries in the oauth_clients table. Next I added the HasApiTokens trait to your User model. Then I added the Passport::routes() call to the AuthServiceProvider and changed the api guard driver from token to passport in config/auth.php. Then I ran the php artisan make:auth command to scaffold out a login system for the provider as this flow requires an authenticated user. Lastly, I created a user in tinker with the default factory provided by Laravel.
Next I moved onto the consumer project. The first needed is to install Guzzle using composer require guzzlehttp/guzzle. Next I added the two routes with the following code.
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => '3',
'redirect_uri' => 'http://consumer.dev/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://provider.dev/oauth/authorize?'.$query);
});
Route::get('/callback', function (\Illuminate\Http\Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://provider.dev/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '3',
'client_secret' => 'OpJbevU3wMcZSMk6PNYLkKe1DmnUctWHTEyTuLME',
'redirect_uri' => 'http://consumer.dev/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});
With that, all of the coding necessary is done. When I visit http://consumer.dev/redirect I get sent to http://provider.dev/oauth/authorize (with the query string of course). Assuming I am not logged into provider.dev I will get sent to the /login page. After I login with the fake user I created earlier I get redirected back where I can either approve or deny the request. Assuming I approve it I will get redirected back to http://consumer.dev/callback with a code query parameter that will trigger the POST request to http://provider.dev/oauth/token and return the access_token and refresh_token.
Just for completeness sake, if you deny the request, guzzle will throw a ClientException that returns the following error from Passport.
{
"error":"invalid_request",
"message":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.",
"hint":"Check the `code` parameter"
}
Lastly this is exactly what the oauth_client that was used looks like in the database.
| id | user_id | name | secret | redirect | personal_access_client | password_client | revoked | created_at | updated_at |
|----|---------|-------------|------------------------------------------|------------------------------|------------------------|-----------------|---------|---------------------|---------------------|
| 3 | 1 | Test Client | OpJbevU3wMcZSMk6PNYLkKe1DmnUctWHTEyTuLME | http://consumer.dev/callback | 0 | 0 | 0 | 2016-12-31 16:07:54 | 2016-12-31 16:07:54 |
All that being said, I don't see a single reason besides the Passport version or your environment to be causing the problem, assuming your code and process matches up. Let me know if you see any discrepancies between your process and mine.
Is there a solution to this?
Like @taitrongnguyen107 , I have been stuck to the same issue. Having followed the same tutorials.
I can make a /request call to passport.dev from consumer.dev. but when I click Approve It redirects to the callback route gives me the exact same error given in the issue title.
I am using passport v2.0.4. Laravel Framework version 5.4.15.
Any help would be appreciated.
Same error here,.. redid the two examples multiple times, but keep getting the same error with the last version of laravel and passport.
Any updates?
Same error...
laravel/framework: v5.4.17
laravel/passport: v2.0.6
{
error: "invalid_client",
message: "Client authentication failed"
}
error.log:
[2017-04-10 13:58:48] production.ERROR: League\OAuth2\Server\Exception\OAuthServerException: Client authentication failed in /vendor/league/oauth2-server/src/Exception/OAuthServerException.php:94
Stack trace:
#0 /vendor/league/oauth2-server/src/Grant/AuthCodeGrant.php(235): League\OAuth2\Server\Exception\OAuthServerException::invalidClient()
#1 /vendor/league/oauth2-server/src/AuthorizationServer.php(140): League\OAuth2\Server\Grant\AuthCodeGrant->validateAuthorizationRequest(Object(Zend\Diactoros\ServerRequest))
#2 /vendor/laravel/passport/src/Http/Controllers/AuthorizationController.php(63): League\OAuth2\Server\AuthorizationServer->validateAuthorizationRequest(Object(Zend\Diactoros\ServerRequest))
#3 /vendor/laravel/passport/src/Http/Controllers/HandlesOAuthErrors.php(25): Laravel\Passport\Http\Controllers\AuthorizationController->Laravel\Passport\Http\Controllers\{closure}()
#4 /vendor/laravel/passport/src/Http/Controllers/AuthorizationController.php(84): Laravel\Passport\Http\Controllers\AuthorizationController->withErrorHandling(Object(Closure))
#5 /vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(47): Laravel\Passport\Http\Controllers\AuthorizationController->authorize(Object(Zend\Diactoros\ServerRequest), Object(Illuminate\Http\Request), Object(Laravel\Passport\ClientRepository), Object(Laravel\Passport\TokenRepository))
#6 /vendor/laravel/framework/src/Illuminate/Routing/Route.php(203): Illuminate\Routing\ControllerDispatcher->dispatch(Object(Illuminate\Routing\Route), Object(Laravel\Passport\Http\Controllers\AuthorizationController), 'authorize')
#7 /vendor/laravel/framework/src/Illuminate/Routing/Route.php(160): Illuminate\Routing\Route->runController()
#8 /vendor/laravel/framework/src/Illuminate/Routing/Router.php(559): Illuminate\Routing\Route->run()
// many rows more....
After debugging the issue many time, and a very helpful suggestion from my colleague I got it working, I used same database for consumer.dev and passport.dev.
Don't know whether this is the right way but I am able to generate my tokens.
Anyone had any success in solving this problem?
I also got this issue, there is just one time that it did work! but i tried to recreate the case and everything goes into error again.
@GautamArya why would we need use the same database for the consumer and passport app, it's just weird. any explanation?
I've solved the issue by
php artisan passport:install
composer require laravel/passport "2.0.6"
below is my code.
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => '1',
'redirect_uri' => 'http://client.dev/callback',
'response_type' => 'code',
'scope' => ''
]);
return redirect('http://tickettit.dev/oauth/authorize?'.$query);
});
Route::get('/callback', function (Illuminate\Http\Request $request) {
$http = new \GuzzleHttp\Client;
$response = $http->post('http://tickettit.dev/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '1',
'client_secret' => 'euwSLAk4UjkaYtKPlQuotL2v5nbyX8qUvGpEnQ49',
'redirect_uri' => 'http://client.dev/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});
I still stuck in this problem...
But I found a strange thing that the Database Table: oauth_auth_codes is empty?!
Is it normal?
Finally, I know the reason...
If you wanna get the Authorization Codes, you must use the following command to generate the client...
php artisan passport:client
Then you will be redirected For Authorization successfully~
Try to compare the data in their tables, you will know the reason.
And you could keep on going!!!
Closing for lack of activity, hope you got the help you needed :)
hi i get the same error too... anyone know whats going on?
I was filling out client_id with the user id instead of oauth_clients id which was causing the error.
make sure personal_access_client and password_client field are both 0 in table oauth_clients
Also it happens when your dev and consume site hosted locally.
It is related to env variables.
So you you can try paste APP_KEY value from .env file as value for config/app.php 'key' like this
'key' => "base64:l84hvor2nIytcH2BpmjWsaatLOp5hY5o9fAGEuTrYPk=",
instead of
'key' => env('APP_KEY'),
I experiencing the same error though all data in database are fresh and correct. :(
Ive had the same problem, I was using email but you must send 'username' ..
if you are not using the default name [Laravel Password Grant Client] please not it down and provide it during testing, i would recommend using blank if you are not sure what you you are doing. Do a php artisan migrate:rollback then php artisan migrate again, then perform a php artisan passport:keys to generate keys then lastly php artisan passport:client --password. Don't type anything, press enter and let laravel generate the password. you should stop experiencing the error
I've solved the problem by
php artisan serve --port=8000 (for provider.dev)
php artisan serve --port=8080 (for consumer.dev)
Set redirect url http://localhost:8080/callback for oauth client
Don't forget set URL's in .env localhost:8000 for provider / localhost:8080 for consumer...
If you want servers on LAN type php artisan serve --host=192.168.?.? --port=8080 (or 8000)
Another possible solution would be to check that you have your JSON configured properly. I have typed 'client_passsword' instead of 'client_secret'.
when I change client_id to 1 in table. It solved
@JiangYulin 👍
I experienced this issue because my "redirect_uri" did not match what was in my oauth_clients table. Changing to the below code allowed me to generate the token:
public function callback(Request $request)
{
$http = new \GuzzleHttp\Client;
$params = [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => $this->oauth_client_id,
'client_secret' => $this->oauth_client_secret,
'redirect_uri' => url('/callback'),
'code' => $request->code,
],
];
$response = $http->post($this->oauth_service_url.'/oauth/token', $params);
return json_decode((string) $response->getBody(), true);
}
@jlarosee I have to login to say "thank you"
Any one found the solution to the problem please help. I have done exactly the same as written in documentation. but still getting error
Client error: POST http://blog.dev/oauth/token resulted in a 400 Bad Request response: {"error":"invalid_request","message":"The request is missing a required parameter, includes an invalid parameter value, (truncated...)
Some update ?
{
"error": "invalid_client"
}
@Sphinxs I'd guess you're getting that response because you're not passing the correct client ID or client secret. OR, your redirect_uri field in the DB is not the same as the host from which you're making the request (presuming you're using access code grant type).
I'm using password grant.
Db

Request
curl -u HtxjZ2ZjlN1y1lD677Y2KPS7:kLF5lJCEzYgce52xURSOc1c8XKbTtJSIuaNLeUdYfePckD47 -XPOST http://127.0.0.1:5000/oauth/token -F grant_type=password -F username=admin -F password=123 -F scope=test
@Sphinxs Check that oauth_clients.password field is set to 1. In Passport, password grant type is a special grant type that must be opted into:
php artisan passport:client --password
https://laravel.com/docs/5.6/passport#password-grant-tokens
please check your redirect uri as same as the url(redirect) in the table(oauth_clients),create a new client and check again,it,s work for me.
$query = http_build_query([
'client_id' => '6',
'redirect_uri' => 'http://127.0.1.7/callback',
'response_type' => 'code',
'scope' => '',
]);
I have the same problem but when I sent requests using Postman the same code works fine. I think the problem is, the sender and receiver both are on the localhost that is causing the problem. Otherwise there is nothing wrong in the Laravel Passport documentation or Passport version.
I have the same problem but when I sent requests using Postman the same code works fine. I think the problem is, the sender and receiver both are on the localhost that is causing the problem. Otherwise there is nothing wrong in the Laravel Passport documentation or Passport version.
True, this is my case :D When you use different ports it works :D
I had same problem for a long time. If both consumer and provider sites are local, it's not working. Use php artisan serve command for the consumer and try that ip address (http://127.0.0.1:8000) instead.
Provider : http://provider.local
Consumer : http://127.0.0.1:8000
Has anyone found any solution? I am running a nuxt app on local domain (localhost:3000) and I am getting:
error: 'invalid_request',
message: 'The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.',
hint: 'Authorization code was not issued to this client'
If I copy and paste the same request on postman, it works, but when I do it using axios, it does not.
I've also tried enabling "password_client" so I can use password grant. It worked, but Laravel makes a request to my callback URL using # instead of ? to pass the parameters (bearer token), and node js does not allow me to get any data after the hashtag.
I finally figured out what was the problem. If you pass your cliend_id as a number like I was doing as shown below:
{
client_id: 3,
redirect_uri: 'http://localhost:3000/oauth',
response_type: 'code',
scope: '*',
client_secret: '5555555555555'
}
It will fail in one of Laravel`s Passport validations as you can see through this link.
So in order to get it working, I only needed to add singlee (or double) quotes like this:
{
client_id: '3',
redirect_uri: 'http://localhost:3000/oauth',
response_type: 'code',
scope: '*',
client_secret: '5555555555555'
}
Oh gosh I spent 3 days to found out it was just about missing quotes. :v
php artisan passport:client --password
it work
I ran into this problem because. My problem was that I have personal_access_client = 1 on the table oauth_clients. This small detail can easily overlooked.
Some update ?
{ "error": "invalid_client" }
turn your password_client to 1 to your database and all its ok
if you tried everything and still it's not working means try this solution!!
just give scope *.
$query = http_build_query([
'client_id' => 1,
'redirect_uri' => 'http://localhost:3000/callback',
'response_type' => 'code',
'scope' => '*'
]);
in my case this is the solution. I have checked
Just for completeness sake, if you deny the request, guzzle will throw a
ClientExceptionthat returns the following error from Passport.{ "error":"invalid_request", "message":"The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.", "hint":"Check the `code` parameter" }
It is exactly this kind of error which https://github.com/thephpleague/oauth2-server/pull/1054 is striving to solve.
Currently, if you "fail" to quote the client id only when it is an integer or perhaps a floating-point number, it will return this error.
Please note that you will start receiving "invalid_request" errors _automatically_ if upgrading to php 7.3 and switching off emulated prepares on PDO.
See the discussion at thephpleague/oauth2-server#1054 for reference.
@remymumoh 's answer works fine for me
make sure personal_access_client and password_client field are both 0 in table oauth_clients
This worked for me.
Is there a solution to this?
create a new client
I have tried different ways, in the end I notice that my config cache is old and I use this code and my problem solved
php artisan config:clear
Most helpful comment
@taitrongnguyen107 In your
oauth_clientstable, do the values you have above exist exactly as you have them in your database?If it doesn't exist exactly like that in the database for
passport.devthen it will throw theinvalid_clienterror. Please be sure to check that and we will see if any further investigation is needed.