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 ?
Related
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 am using Laravel to call an external API.
This is my Client:
<?php
use GuzzleHttp\Client;
$client = new Client();
$response = $client->request('POST',
'https://example.org/oauth/token', [
'headers' => [
'cache-control' => 'no-cache',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'form_params' => [
'client_id' => '2',
'client_secret' => 'client-secret',
'grant_type' => 'password',
'username' => 'username',
'password' => 'password',
],
]);
$accessToken = json_decode((string)$response->getBody(),
true)['access_token'];
Now I can use this to fetch something:
<?php
$response = $client->request('GET',
'https://example.org/api/items/index', [
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'Bearer '.$accessToken,
],
]);
So now I don't want to initiate the client on every method again. So maybe there's a cool/Laravel-like way to provide the $client to the controller on specific routes?
I thought about an app service provider or an middleware, but I'd love to see an example :-)
Perhaps you can use singleton? Wrap your implementation in a class lets say YourHttpClient then in your AppServiceProviders register method add:
$this->app->singleton('YourHttpClient', function ($app) {
return new YourHttpClient();
});
Then you should be able to typehint it in your controller constructors like this
class SomeController {
private $client;
public function __construct(YourHttpClient $client) {
$this->client = $client;
}
}
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.
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));