I'm trying to obtain an access token from Google so I can use a 'service account' to upload videos to YouTube automatically.
This code:
$credentials = array(
'client_id' => $my_client_id
);
$jwt = JWT::encode($credentials, $private_key);
$client = new Google_Client();
if ($client->authenticate($jwt))
{
// do something
}
Fails with this exception:
Fatal error: Uncaught exception 'Google_Auth_Exception' with message 'Error fetching OAuth2 access token, message: 'invalid_request: Client must specify either client_id or client_assertion, not both'' in /home/google/client/google-api-php-client/src/Google/Auth/OAuth2.php:120
Where am I going wrong?
TY!
I had missed a large section of the documentation as shown here:
https://developers.google.com/accounts/docs/OAuth2ServiceAccount#creatingjwt
I had also missed that the algorithm had to be RSA256 not HSA256 as defaulted to in the JWT PHP encode function.
And further, that I needed to POST a request, appropriately, directly to get an access token to endpoint:
https://www.googleapis.com/oauth2/v3/token
The Google private JSON private key for the service account also was invalid for use by openssl due to the final character being encoded/included as:
\u003d
Swapping this, literally, with:
=
solved that problem.
Here is my now working (ish, see closing statement) code:
$claimset = array(
'iss' => $client_email,
'scope' => 'https://www.googleapis.com/auth/youtube.upload',
'aud' => 'https://www.googleapis.com/oauth2/v3/token',
'exp' => time() + 1800,
'iat' => time(),
'sub' => 'my google account email#gmail.com'); // not sure if reqd
$jwt = JWT::encode($claimset, $private_key, 'RS256');
// Now need to get a token by posting the above to:
// https://www.googleapis.com/oauth2/v3/token
# Our new data
$data = array(
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
);
# Create a connection
$url = 'https://www.googleapis.com/oauth2/v3/token';
$ch = curl_init($url);
# Form data string
$postString = http_build_query($data, '', '&');
# Setting our options
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postString);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
# Get the response
$response = curl_exec($ch);
curl_close($ch);
print "and here is what we got: ";
print_r($response);
exit;
Unfortunately, for some reason the response I'm getting is:
{ "error": "unauthorized_client", "error_description": "Unauthorized client or scope in request." }
Suspect my service account does not yet have the right to upload to YouTube.
I'm not an experr, but you should probably look at removing the "," at the end of you line here:
'client_id' => $private_key['client_id'],
//'client_email' => $private_ket['client_email']
change to:
'client_id' => $private_key['client_id']
//'client_email' => $private_ket['client_email']
I've used this example to get oauth working. It may be helpful:
http://msdn.microsoft.com/en-us/library/dn632721.aspx
you could also try oauth testing here:
https://developers.google.com/oauthplayground/
Good luck!
Related
I'm trying to implement an Authorization code grant with Socialite. I'm able successfully to receive users in the callback, but struggling to set up the other part of auth. I've created the personal passport client and received the client ID & Secret in oauth_clients. Whenever I use the createToken() I am able to see oauth_access_tokens these tokens with the name of PKCE(which contains the same name as in oauth_client). The $code is taken from the query in the callback, however, the $response in the very end is null, any idea why?
public function callbackGoogle()
{
// Receive the user credentials from social
$googleUser = Socialite::driver('google')->stateless()->user();
// Get the user by email
$user = User::where('email', $googleUser->email)->first();
// Create token
$user->createToken('PKCE')->accessToken;
// Get query parameter code from callback
$code = request()->query()['code'];
// Get client data
$client = DB::table('oauth_clients')->where('name', 'PKCE')->first();
$response = Http::asForm()->post('http://localhost:5000/oauth/token', [
'grant_type' => 'authorization_code',
'client_id' => $client->id,
'client_secret' => $client->secret,
'code' => urldecode($code),
'redirect_uri' => $client->redirect,
]);
// // Receiving null
dd($response->json());
}
You are trying to exchange an access token from google with your own application.
This does not make sense.
With this line:
$googleUser = Socialite::driver('google')->stateless()->user();
You have already exchanged the code from the URL with a token from google.
If you want to get an API token for your API, you already did this with
$user->createToken('PKCE')->accessToken;
You could use
$token = $user->createToken('PKCE')->accessToken;
I have a question about autoloading in Laravel.
I am trying to use an API to translate a web site. I typed in the code given by the provider in the controller and I got the following error message.
require(vendor\autoload.php): failed to open stream: No such file or directory
This is the code.
require 'vendor\autoload.php'; <=★Here★
session_start();
define('URL', '');
define('KEY', '');
define('SECRET', '');
define('NAME', '');
$api_name = '';
$api_param = '';
$provider = new \League\OAuth2\Client\Provider\GenericProvider(
[
'clientId' => KEY,
'clientSecret' => SECRET,
'redirectUri' => '',
'urlAuthorize' => '',
'urlAccessToken' => URL . '/oauth2/token.php',
'urlResourceOwnerDetails' => '',
],
);
try {
// Try to get an access token using the authorization code grant.
$accessToken = $provider->getAccessToken('client_credentials');
// The provider provides a way to get an authenticated API request for
// the service, using the access token; it returns an object conforming
// to Psr\Http\Message\RequestInterface.
$params = array(
'access_token' => $accessToken->getToken(),
'key' => KEY,
'api_name' => $api_name,
'api_param' => $api_param,
'name' => NAME,
'type' => 'xml',
'xxx' => 'xxx',
);
$request = $provider->getAuthenticatedRequest(
'POST',
URL . '/api/?' . http_build_query($params),
$accessToken,
);
$response = $provider->getResponse($request);
$data = $response->getBody()->getContents();
print_r($data);
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
// Failed to get the access token or user details.
exit($e->getMessage());
}
I checked the file pointed out in the error message and actually autoload.php file was in the vendor folder. I did some research and I found some web sites saying that I should add a directory in composer.json but I wasn't so sure what I should do.
I appreciate if you could tell me what I'm doing wrong or what I should do. Any help would be appreciated as I have tried multiple methods with no success.
Thank you in advance.
I want to integrate users of my Joomla site into sugarcrm panel. I'm using SuiteCRM Version 7.7.6 [Sugar Version 6.5.24 (Build 509)] and trying to import csv file of users into contact list of sugarcrm through hook.
Means I want to build functionality for auto integration in between Joomla and Sugarcrm site. When a new user register on Joomla site, they should be auto added in the contact list of crm panel.
Is there any possible way to implement this integration ?
I have got a solution to integrate records in a particular module of sugarcrm through Rest API.
Create php file anywhere outside your CRM project directory and write API code as given below.
Need to set site URL of sugarcrm and configure admin username and password in API.
After that, set module name in which you want to add data.
Adjust your data in given array format.
Now just hit the file URL on browser where you placed this API.
Data will be successfully added in the required module.
API Code:
$url = "http://{site_url}/service/v4_1/rest.php";
$username = "admin";
$password = "password";
//function to make cURL request
function call($method, $parameters, $url)
{
ob_start();
$curl_reque**strong text**st = curl_init();
curl_setopt($curl_request, CURLOPT_URL, $url);
curl_setopt($curl_request, CURLOPT_POST, 1);
curl_setopt($curl_request, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($curl_request, CURLOPT_HEADER, 1);
curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_request, CURLOPT_FOLLOWLOCATION, 0);
$jsonEncodedData = json_encode($parameters);
$post = array(
"method" => $method,
"input_type" => "JSON",
"response_type" => "JSON",
"rest_data" => $jsonEncodedData
);
curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post);
$result = curl_exec($curl_request);
curl_close($curl_request);
$result = explode("\r\n\r\n", $result, 2);
$response = json_decode($result[1]);
ob_end_flush();
return $response;
}
//login --------------------------------------------
$login_parameters = array(
"user_auth" => array(
"user_name" => $username,
"password" => md5($password),
"version" => "1"
),
"application_name" => "RestTest",
"name_value_list" => array(),
);
$login_result = call("login", $login_parameters, $url);
/*
echo "<pre>";
print_r($login_result);
echo "</pre>";
*/
//get session id
$session_id = $login_result->id;
//create contacts ------------------------------------
$set_entries_parameters = array(
//session id
"session" => $session_id,
//The name of the module from which to retrieve records.
"module_name" => "Contacts",
//Record attributes
"name_value_list" => array(
array(
//to update a record, you will nee to pass in a record id as commented below
//array("name" => "id", "value" => "912e58c0-73e9-9cb6-c84e-4ff34d62620e"),
array("name" => "first_name", "value" => "John"),
array("name" => "last_name", "value" => "Smith"),
),
array(
//to update a record, you will nee to pass in a record id as commented below
//array("name" => "id", "value" => "99d6ddfd-7d52-d45b-eba8-4ff34d684964"),
array("name" => "first_name", "value" => "Jane"),
array("name" => "last_name", "value" => "Doe"),
),
),
);
$set_entries_result = call("set_entries", $set_entries_parameters, $url);
echo "<pre>";
print_r($set_entries_result);
echo "</pre>";
Click here for more details:
http://support.sugarcrm.com/Documentation/Sugar_Developer/Sugar_Developer_Guide_6.5/Application_Framework/Web_Services/Examples/REST/PHP/Creating_or_Updating_Multiple_Records/
Yes it would be possible, although not practicable to do in a hook.
If you need to import a CSV more than once, implementing a scheduler job for the import might be a good idea.
However you could actually not use CSV at all and let Joomla or an intermediate script push the data to sugar in real-time or a time interval of your choice using the REST API of your CRM.
I'm currently stuck trying to create a payment with Omnipay. I have the following libraries installed in my project:
https://github.com/barryvdh/laravel-omnipay
https://github.com/thephpleague/omnipay-mollie
But I'm having problems starting. I see in the example that I need these params:
$params = [
'amount' => $order->amount,
'issuer' => $issuerId,
'description' => $order->description,
'returnUrl' => URL::action('PurchaseController#return', [$order->id]),
];
But what's the $issuerId? I would like to have an integration with Mollie.
Does someone maybe has an example of using laravel Omnipay with Mollie?
UPDATE:
I'm trying to submit my form with an ajax call. In my PHP function I have the following code:
$gateway = Omnipay\Omnipay::create('Mollie');
$gateway->setApiKey('test_gSDS4xNA96AfNmmdwB3fAA47zS84KN');
$params = [
'amount' => $ticket_order['order_total'] + $ticket_order['organiser_booking_fee'],
'description' => 'Kapelhoek wijkfeesten',
'returnUrl' => URL::action('EventCheckoutController#fallback'),
];
$response = $gateway->purchase($params)->send();
if ($response->isSuccessful()) {
// payment was successful: update database
print_r($response); die;
} elseif ($response->isRedirect()) {
// redirect to offsite payment gateway
return $response->getRedirectResponse(); die;
} else {
// payment failed: display message to customer
echo $response->getMessage(); die;
}
But now I'm getting the following console error:
XMLHttpRequest cannot load https://www.mollie.com/payscreen/select-method/PRMtm6qnWG. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://kapelhoektickets.dev' is therefore not allowed access.
How can I fix this?
But what's the $issuerId?
Issuer ID is The issuer's unique identifier, for example ideal_ABNANL2A. When creating a payment, specify this ID as the issuer parameter to forward the consumer to their banking environment directly.
You can see a list of available issuers by calling this API url:
https://api.mollie.nl/v1/issuers
as stated in https://www.mollie.com/be/docs/reference/issuers/list
To read more about the issuer visit this part of the API-documentation:
https://www.mollie.com/be/docs/reference/issuers/get
I want to create a label in gmail account using goggle admin sdk api.
I am sending a Http Post Request to
https://apps-apis.google.com/a/feeds/emailsettings/2.0/{domain}/{username}/label/
But i get this response :-
Invalid domain.
Error 403
Following is the code for this task :-
$domain = explode('#',$user->email);
$headers = array(
"X-HTTP-Method-Override: POST",
"Authorization: {$obj->token_type} "." {$obj->access_token}",
"Content-type: application/atom+xml",
);
$options = array(CURLOPT_URL => "https://apps-apis.google.com/a/feeds/emailsettings/2.0/$domain[1]/$domain[0]/label",
CURLOPT_HEADER => 1,
CURLOPT_RETURNTRANSFER => 1,
// CURLOPT_USERAGENT => '',
CURLOPT_FOLLOWLOCATION => 1,
// CURLOPT_VERBOSE => 1,
// CURLOPT_POST => true
);
$ch = curl_init();
curl_setopt_array($ch, $options);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
echo "<pre>";print_r($result);echo"</pre>";
If you actually trying to access labels on your gmail.com account from your domain's admin account, it will not work. The email setting API works only on Premier and Edu Google Apps domains administrators.