I'm trying to create a bearer token for passport so I can use my api routes internally. I send a post request to /oauth/token with the client id and client secret. The code that generates the bearer token looks like this.
public function generateToken() {
try {
$req = Request::create('/oauth/token', 'POST', [
'grant_type' => 'client_credentials',
'client_id' => '1',
'client_secret' => 'POe81tKvmZ0DhBdtwdM7VPoV5tTKobVYzSc9A0RX',
'scope' => '*',
]);
$res = app()->handle($req);
return $res;
} catch (Exception $e){
log::critical('Failed to generate bearer token.');
} catch (error $e) {
log::critical('Failed to generate bearer token.');
}
}
However when trying to do this request I get a 401 authorised.
#content: "{"error":"invalid_client","message":"Client authentication failed"}" #version: "1.1"#statusCode: 401 #statusText: "Unauthorized"
Is there anyway of fixing this?
This works for me
$client = new client(['verify' => false]);
$response = $client->post($url, [
'form_params' => [
'client_id' => 5,
// The secret generated when you ran: php artisan passport:install
'client_secret' => 'HxLB5LVi3HhHxYkoHVZinoYUz5Ab3HnbWmiB1KBd',
'grant_type' => 'client_credentials',
'scope' => '*',
]
]);
Related
I am trying to implement BlueSnap payment(Embedded Checkout) on my WebApp in Laravel 6.
https://developers.bluesnap.com/v8976-Tools/docs/embedded-checkout.
I allowed server and public IP to access the BlueSnap Sandbox routes
First, I am getting the token from BlueSnap and this work perfect.
https://developers.bluesnap.com/v8976-Tools/docs/create-embedded-checkout-token.
But then, when I request for card transaction (https://developers.bluesnap.com/v8976-JSON/docs/auth-capture), with "pfToken" which I get from previous request, I am getting 401.
public function makePayment(Request $request) {
$endpoint = 'https://sandbox.bluesnap.com/services/2/transactions';
try {
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', $endpoint, [
'headers' => [
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'Authorization' => 'Basic dXNlcm5hbWU6cGFzc3dvcmQ='
],
'json' => [
'cardTransactionType' => 'AUTH_CAPTURE',
'amount' => '25.00',
'currency' => 'USD',
'pfToken' => $request->token,
],
]);
} catch (RequestException $e) {
dd($e);
}
dd($response);
}
I also tried to send request with Postman, and I got same error.
I am having trouble getting a laravel application to access an api endpoint in another laravel app, same server. I can get it to work in terminal, and postman but not from the laravel app itself, both getting an auth token and using work in p;ostman and terminal but not in laravel. (killing me that this was working the other day)
I have tried many Guzzle and curl configs, Using WAMP on Win 10. Laravel Framework version 5.3.31, PHP 7.2.18
try {
$response = $http->request('POST',$this->base_oauth_url. 'oauth/token', [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/x-www-form-urlencoded',
],
'form_params' => [
'grant_type' => 'password',
'client_id' => self::API_CLIENT_ID,
'client_secret' => self::API_SECRET,
'username' => self::API_USERNAME,
'password' => self::API_PASSWORD,
'scope' => '*',
],
'debug'=>$this->debug,
'allow_redirects' => false,
'verify' => false,
]);
} catch (ClientException $e) {
throw new Exception("Guzzle Error: {$e->getMessage()}");
} catch (Exception $e) {
throw new Exception("Send Error: ({$e->getCode()}): {$e->getMessage()}");
}
$response = json_decode((string) $response->getBody()->getContents());
$data = array();
$data['access_token'] = $response->access_token;
$data['refresh_token'] = $response->refresh_token;
Error:
Guzzle Error: Client error: POST http://mytestdomain.com/oauth/token resulted in a 401 Unauthorized response:
{"error":"invalid_client","message":"Client authentication failed"}
Greetings and Regards
I am designing an api with Laravel and using a passport for an app.
I'm having trouble logging in using the login endpoint.
The problem I encountered is as follows:
I will send the necessary parameters to the server including
client_id - grant_type - username - password - client_secret - scope:
{{server_url}}/api / v1 / login
In the login method:
After evaluating entries I send a request to oauth/token to receive theta token.
I get the error below.
GuzzleHttp\Exception\ClientException: Client error: POST
http://divar.local/oauth/token resulted in a 400 Bad Request
response: {"error":"invalid_grant","error_description":"The provided
authorization grant (e.g., authorization code, resource owner
(truncated...)
The contents of the login method
public function login()
{
$validator = Validator::make(request()->all(), [
'mobile_number' => 'required',
'password' => 'required',
]);
if ($validator->fails()) {
$response['errors'] = $validator->errors();
return response()->json($response, 401);
}
$clientOauthData = Client::where('password_client', 1)->where('name', 'Laravel Password Grant Client')->first();
$http = new \GuzzleHttp\Client;
$response = $http->post(env('APP_URL') . '/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => $clientOauthData->id,
'client_secret' => $clientOauthData->secret,
'username' => request('mobile_number'),
'password' => request('password'),
'scope' => '',
],
'headers' => [
'Accept' => 'application/json'
]
]);
$response = json_decode((string)$response->getBody(), true);
return response()->json($response, 200);
}
Request headers :
Request body :
This is how I always proceed this request.
public function login(Request $request)
{
$this->validate($request, [
'email' => 'required|mobile_phone',
'password' => 'required|string',
]);
$http = new \GuzzleHttp\Client;
try {
$response = $http->post(config('services.passport.login_endpoint'), [
'form_params' => [
'grant_type' => 'password',
'client_id' => 'your client ID',
'client_secret' => 'secret ID,
'username' => $request->mobile_phone,
'password' => $request->password,
// 'scope' => '',
],
]);
return $response->getBody();
} catch (\GuzzleHttp\Exception\BadResponseException $e) {
if ($e->getCode() == 401) {
return response()->json(['message' => 'This action can\'t be perfomed at this time. Please try later.'], $e->getCode());
} else if ($e->getCode() == 400) {
return response()->json(['message' => 'These credentials do not match our records.'], $e->getCode());
}
return response()->json('Something went wrong on the server. Please try letar.', $e->getCode());
}
}
I'm setting up Laravel Passport's Client Grant and using Guzzle to retrieve a token, but I'm getting a 401 Unauthorized error.
I created the client using: php artisan passport:client --client.
The client generated is:
Client ID: 1
Client secret: NmJsEVFClXVqWJuQnZTWA3bnZEVZ0KaC13anHZt1
I saved these in my .env file and ran the command
php artisan config:clear
Here's my code:
$url = 'http://hub.local/oauth/token';
$client_secret = env('CLIENT_SECRET');
$client_id = env('CLIENT_ID');
$client = new Client();
try {
$response = $client->post($url, [
'json' => [
'grant_type' => 'client_credentials',
'client_id' => $client_id,
'client_secret' => $client_secret,
],
'headers' => [
'Content-Type' => 'application/json',
],
]);
return $response;
} catch (RequestException $e) {
dd($e);
} catch (Exception $e) {
dd($e);
}
And the resulting error message:
ClientException {#660 ▼
-request: Request {#649 ▶}
-response: Response {#657 ▶}
-handlerContext: []
#message: """
Client error: `POST http://hub.local/oauth/token` resulted in a `401 Unauthorized` response:
{"error":"invalid_client","error_description":"Client authentication failed","message":"Client authentication failed"}
"""
#code: 401
#file: "C:\repos\client\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php"
#line: 113
When I try the request using the same parameters and values in Insomnia, the request works.
Seems I can't post images yet.
https://i.imgur.com/w6Ollin.jpg
https://imgur.com/fXpzKjj.jpg
I'm using Laravel 5.8.12, Guzzle 6.3.3 and Passport 7.2.2.
What am I missing?
Update: The problem only occurred when I was running the ( Laravel) client and server instances on the same local xampp server. I separated them to run on their own individual xampp instances and the authentication worked without issue. What had confused me while testing solely locally was that the request worked with Insomnia, but not the browser. I'm assuming that the "machine to machine" part of this client grant was seeing my client + server sharing the same xampp instance as something unrecognized. In any event, there's no actual problem. Hopefully this helps someone else.
in laravel doc there is an example like this :
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);
});
when I tested this one with my info I changed to some thing like this :
Route::get('/users/login', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://payment.devenv/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 2,
'client_secret' => 'z8YWlJeaW0d7o7SFyPLISUxYOcO5CxjGrZ5YuItl',
'username' => 'athamidn#gmail.com',
'password' => '123456',
'scope' => '',
'code' => 200,
'redirect_uri' => 'http://example.com/callback',
],
]);
return json_decode((string) $response->getBody(), true);
});
And I received an error same with your error. After many hours I got issue :
In database at oauth_clients table this is my info :
2 name: Laravel Password Grant Client redirect: http://localhost
when I changed redirect url to this it works.
finally :
Route::get('/users/login', function (Request $request) {
$http = new GuzzleHttp\Client;
$response = $http->post('http://payment.devenv/oauth/token', [
'form_params' => [
'grant_type' => 'password',
'client_id' => 2,
'client_secret' => 'z8YWlJeaW0d7o7SFyPLISUxYOcO5CxjGrZ5YuItl',
'username' => 'athamidn#gmail.com',
'password' => '123456',
'scope' => '',
'code' => 200,
'redirect_uri' => 'http://localhost'
],
]);
return json_decode((string) $response->getBody(), true);
});
I believe you can re-create passport public and private keys stored in /storage folder by executing the php artisan passport:install. Then you can define those keys in the .env file and pass it with client_id & client_secret.
command output
Personal access client created successfully.
Client ID: 31
Client secret: xxxx
Password grant client created successfully.
Client ID: 32
Client secret: xxxx
/.env
PERSONAL_CLIENT_ID=31
PERSONAL_CLIENT_SECRET=xxxx
PASSWORD_CLIENT_ID=32
PASSWORD_CLIENT_SECRET=xxxx
POST - API parameters - /oauth/token
'client_id' => env('PASSWORD_CLIENT_ID'),
'client_secret' => env('PASSWORD_CLIENT_SECRET')
This error could happen when those private and public keys are not matched properly with the already created ones.
Cheers!
I am using a Laravel version 5.5 using Passport for authentication.
I have successfully create the token and can access it using the auth:api middleware.
But whenever user login into system it create new token for that user. I just want to refresh user last token and send it back instead of creating a new token.
I have used the following code to generate auth token
$token = $user->createToken('string-'.$user->id)->accessToken;
It generate the token with 1075 characters but when i checked in database table oauth_access_tokens it shows me the token with 80 characters.
How can i get last generated token using 80 character token and refresh it and send it back?
Thanks in Advance
If your application issues short-lived access tokens, users will need to refresh their access tokens via the refresh token that was provided to them when the access token was issued. In this example, we'll use the Guzzle HTTP library to refresh the token:
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => 'the-refresh-token',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
This /oauth/token route will return a JSON response containing access_token, refresh_token, and expires_in attributes. The expires_in attribute contains the number of seconds until the access token expires.
I've done something like.
Created an endpoint for grant refresh token.
and in my controller,
public function userRefreshToken(Request $request)
{
$client = DB::table('oauth_clients')
->where('password_client', true)
->first();
$data = [
'grant_type' => 'refresh_token',
'refresh_token' => $request->refresh_token,
'client_id' => $client->id,
'client_secret' => $client->secret,
'scope' => ''
];
$request = Request::create('/oauth/token', 'POST', $data);
$content = json_decode(app()->handle($request)->getContent());
return response()->json([
'error' => false,
'data' => [
'meta' => [
'token' => $content->access_token,
'refresh_token' => $content->refresh_token,
'type' => 'Bearer'
]
]
], Response::HTTP_OK);
}