I am using laravel passport to creat oauth .
use Illuminate\Http\Request;
Route::get('/redirect', function () {
$query = http_build_query([
'client_id' => '3',
'redirect_uri' => 'http://127.0.0.1:8000/auth/callback',
'response_type' => 'code',
'scope' => '',
]);
return redirect('http://127.0.0.1:8000/oauth/authorize?'.$query);
});
Route::get('/auth/callback', function (Request $request) {
$http = new \GuzzleHttp\Client;
$response = $http->post('http://127.0.0.1:8000/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '3',
'client_secret' => 'client_secret',
'redirect_uri' => 'http://127.0.0.1:8000/auth/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});
Here Redirecting For Authorization is successful and while Converting Authorization Codes To Access Tokens using Guzzle the page keeps loading with out returning any response here.
Even using CURL inside is returning false. But while trying from post man or CURL from diffrent destination it returns valid data. Is it framwork/package bug?
do not use GuzzleHttp
use this code:
$request->request->add([
'username' => $request->email,
'password' => $request->password,
'grant_type' => 'password',
'client_id' => '2',
'client_secret' => 'GT6IA4aasdasdBhgrPvxHkGeXBasdasdST5F',
'scope' => ''
]);
$tokenRequest = Request::create(
url('oauth/token'),
'post'
);
$response = Route::dispatch($tokenRequest);
and do not forget to add this on the top
use Illuminate\Support\Facades\Route;
Probably you run your code on PHP's integrated web server. If yes, then it won't work, because it's able to handle only one request concurrently. So, if you do an HTTP request from a local script to another local script... Then you have a deadlock.
Try to run PHP-FPM locally instead.
Related
Since upgrading my application from Laravel 7 to 8, I've been having some minor issues with Laravel Passport. I created a test feature to retrieve a Passport token to make sure it was working, but I can't get it back. When I call passport.token I always get the same message:
array:3 [
"error" => "invalid_client"
"error_description" => "Client authentication failed"
"message" => "Client authentication failed"
]
I have tried several things, but here is my current code:
use Illuminate\Support\Str;
use Laravel\Passport\Client as OauthClient;
use Modules\Sapiendo\Tests\SapiendoTestCase;
/** #test */
public function we_can_authenticate_and_use_api_endpoints_with_client_credential_grant_token()
{
$customer = $this->createFullCustomer();
/** #var OauthClient $oauthClient */
$oauthClient = OauthClient::create([
'user_id' => null,
'name' => 'ClientCredentials Grant Client',
'secret' => Str::random(40),
'redirect' => 'http://localhost',
'personal_access_client' => false,
'password_client' => false,
'revoked' => false,
]);
$state = Str::random(40);
$autorization = $this->get(route('passport.authorizations.authorize', [
'client_id' => $oauthClient->id,
'redirect_uri' => 'http://localhost',
'response_type' => 'code',
'scope' => '',
'state' => $state,
]));
$autorization->assertStatus(302);
// D'abord on demande un token avec les identifiants créés
$tokenRequest = $this->post(route('passport.token'), [
'grant_type' => 'client_credentials',
'client_id' => $oauthClient->getKey(),
'client_secret' => $oauthClient->secret,
'code' => $state,
]);
//->assertSuccessful();
dd($tokenRequest->json());
...
Before this update I didn't have to go through the passport.authorizations.authorize route to get the code, I could go directly to the passport.token step
Since Passport 9.0, the client ID and secret are hashed. There is a function to retrieve this non-hashed secret from the Passport client object
$oauthClient = OauthClient::create([
'user_id' => null,
'name' => 'ClientCredentials Grant Client',
'secret' => Str::random(40),
'redirect' => 'http://localhost',
'personal_access_client' => false,
'password_client' => false,
'revoked' => false,
]);
$tokenRequest = $this->post(route('passport.token'), [
'grant_type' => 'client_credentials',
'client_id' => $oauthClient->id,
'client_secret' => $oauthClient->getPlainSecretAttribute(),
'code' => $state,
]);
I've installed Laravel Passport.
Here is how I generate auth code:
public function auth(Request $request)
{
$request->session()->put('state', $state = Str::random(40));
$request->session()->put(
'code_verifier', $code_verifier = Str::random(128)
);
$codeChallenge = strtr(rtrim(
base64_encode(hash('sha256', $code_verifier, true))
, '='), '+/', '-_');
$query = http_build_query([
'client_id' => '1',
'redirect_uri' => 'http://127.0.0.1:8000/authorize/response',
'response_type' => 'code',
'scope' => '',
'state' => $state,
'code_challenge' => $codeChallenge,
'code_challenge_method' => 'S256',
]);
return redirect('http://127.0.0.1:9000/oauth/authorize?'.$query);
}
Above request all passes well.
Here is how I try to generate access token:
public function authResponse(Request $request)
{
$state = $request->session()->pull('state');
throw_unless(
strlen($state) > 0 && $state === $request->state,
InvalidArgumentException::class
);
$response = Http::asForm()->post('http://127.0.0.1:9000/oauth/token', [
'grant_type' => 'authorization_code',
'client_id' => '1',
'client_secret' => 'hYMELQ1VKAWrG0TwrkM3JxUuoICSCWCzCztClZZi',
'redirect_uri' => 'http://127.0.0.1:8000/authorize/response',
'code' => $request->code,
]);
return $response->json();
}
When I execute the code for generating the access token I get the following error:
{"error":"invalid_client","error_description":"Client authentication
failed","message":"Client authentication failed"}
Any idea what can be the cause of this error? I've taken the client_secret from the DB.
Any idea what can be the problem and how can I fix it?
You are missing to pull from session the code_verifier on your authResponse() method.
$codeVerifier = $request->session()->pull('code_verifier');
Then add the $codeVerifier to the 'code_verifier' in post method when your are converting authorization codes to access tokens.
$response = Http::asForm()->post('http://127.0.0.1:9000/oauth/token', [
'grant_type' => 'authorization_code',
'client_id' => '1',
'client_secret' => 'hYMELQ1VKAWrG0TwrkM3JxUuoICSCWCzCztClZZi',
'redirect_uri' => 'http://127.0.0.1:8000/authorize/response',
'code' => $request->code,
]);
Check out the docs about this.
I use laravel and GuzzleHttp for send post request same as following
$client = new Client(['verify' => false]);
$data = [
'headers' => [
'Authorization' => 'code',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'form-params' => [
'redirect_uri' => 'http://localhost',
'code' => 'MZTADnFF6m'
]
];
$response = $client->request('POST', 'https://oom.com', $data);
but my problem is 'http://localhost' send as 'http:\/\/localhost' to api server
how can i fix this problem?
You can use stripslashes() for achieve this. You can try
stripslashes("http:\/\/localhost");
it will resultd in
http://localhost
as a result
use urlencode
here it is
'redirect_uri' => urlencode('http://localhost'),
I tried a lot of things but for now is impossible to me to get the refresh token using api routes. Here is my code. In API.php
<?php
use Illuminate\Http\Request;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;
use Laravel\Passport\Http\Controllers\AccessTokenController;
Route::post('connect', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://127.0.0.1:8000/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => $request->client_id,
'client_secret' => $request->client_secret,
'username' => $request->username,
'password' => $request->password,
'scope' => ''
],
]);
return json_decode((string) $response->getBody(), true);
});
It always returns the same error:
Error creating resource: [message] fopen(http://127.0.0.1:8000/oauth/token): failed to open stream: HTTP request failed! [file] /var/www/html/passport_test_3/vendor/guzzlehttp/guzzle/src/Handler/StreamHandler.php
Any help ?
I successfully create server and client app both using laravel, I can access data from server app to client app also. But now I want to create another client app using codeigniter. Authorization works except for the callback method. So how can I convert the this code
Route::get('/callback', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'redirect_uri' => 'http://example.com/callback',
'code' => $request->code,
],
]);
return json_decode((string) $response->getBody(), true);
});
into CodeIgniter 2?
Thanks
Anyways, I already fixed it.
adding "guzzlehttp/guzzle": "~6.0" in composer.json
running composer update
callback method code
$http = new \GuzzleHttp\Client;
$response = $http->post('http://localhost:8000/oauth/token', [
'form_params' => [
'grant_type' => 'authorization_code',
'client_id' => '3',
'client_secret' => 'client-secret-from-db',
'redirect_uri' => 'ci-client-app/callback',
'code' => $this->input->get('code', TRUE)
],
]);
echo '<pre>', print_r(json_decode((string) $response->getBody(), true));