Intuit App: Error while getting accessTokenKey for OAuth 2.0 - php

I am new in Quickbooks and want to use the API by OAuth 2.0 protocol. For that, I did the following steps according to Quickbooks docs.
I have created an Intuit Developer account.
I have created an application for testing purposes.
I got OAuth keys for my test application.
I want to do API requests by using PHP SDK provided by Quickbooks and I started to use code according to the instructions of PHP SDK:
require "vendor/autoload.php";
use QuickBooksOnline\API\DataService\DataService;
$dataService = DataService::Configure(array(
'auth_mode' => 'oauth2',
'ClientID' => "Q0lCkcEshsGMHOEula2r5RKc2yhxvMsYEpKN1lw1WZwyfd1Si6",
'ClientSecret' => "gE0F9hLgwx9OBzRpNxyOvWJH6L2fIhzAwBugPJHq",
'accessTokenKey' => 'eyJlbmMiOiJBMTI4Q0JDLUhTMjU2IiwiYWxnIjoiZGlyIn0..4z4Assj4x1qt8H4DtQco6A.nmV2jTxaDMVdFWEUO16q5qhbd5aD6U-U-RYnSNywqg-HPC_3_jvwpMJU1a1S5X-PgPUy60WvVy_8p1awY7kIoFzTV4IhdFLrZpYtBUGCjcsvjxWeOSgP6oCayBEmCv7zzabtgB6vxU46jQqKX2IXYUGPPtyYO64hrgELFR4SKUK6boZiVnh8z19gnvsReKMmIINA3-NgC6QJqMRp6HWgzCa9RuDN9tCtrAK2dy5xmJRNSNgdv_gyg1bfdX4l4b30fLPzFk31fsTT9NTJq9PuGtdTsvUuCj7Hme6HPldD9TKYRXWU8TKrQQrQWEpdlbPr6F3rhP6IdmCv9t1XH_WzF_1IseRUoYhiTUjubig-j8gzwajIdYQTzpJQKJ92QiAEyt8k40WWg0v69hEC0w7WRBuUE-IJ50xWypqS_P28IWt1G14rovZ97soGOteSik-41g1icR2zxfNhXGq7zO7oU5B8r-ej5Pb52T0MCMktgd6y32bqwo2pcEzblL2bZs7DZ7LDx5peY4TIfGW21crTE6xjhRr7LdqB8K505pRqIOP20eaRgwtGHLZ3bdBt1_negw2AGjc409BM0nLzzmODxr3yo-YdGwkcOjm5QgbGAsrnpoSo9tSpxPHoN0vMRneRdsKCd6CZG5M1OIOMuj7spkm442tvwiAMCx2Fh-STG6fMnhOq7l_f8NW_3kscxtF2.obQxJKjPfi1KlaQQ_OUoNg',
'refreshTokenKey' => "L011509163184Q0K7DT40SVXhJXAfyoj6B6EbSr3Ty64yVvF5A",
'QBORealmID' => "123145857569084",
'baseUrl' => "https://sandbox-quickbooks.api.intuit.com"
));
I am stacked on getting accessTokenKey in order to complete configurations and start to do API requests. QuickBooks provides a tool named OAuth Playground here for getting accessTokenKey. I put Client ID and Client Secret from Application's Keys as Consumer Key and Consumer Secret in the OAuth Playground's screen and press Connect to QiuckBooks but it gives me this error:
We were unable to process your request.
This error can occur when too much time has passed in the request. We have been notified of the problem and will investigate further.
Please contact us for further assistance.
Error Id: cxgdknrkjzppmjifkv2ipsgp-29491421
Could anyone help me with this error?

Related

AWS dynamodb query from php

I have a react application and i'm trying to use aws dynamodb, i installed the php sdk but i don't know how to query my db.
I copied the tutorial here and i changed the endpoint to: "https://dynamodb.us-west-2.amazonaws.com".
I get this error: {"__type":"com.amazon.coral.service#UnrecognizedClientException","message":"The security token included in the request is invalid."}. I guess i have to add a security token somewhere, i don't know where and neither where to find it.
Any suggestion?
Based on your error, i think you need to check your aws secret key and access key. You can try to install aws cli then create user access programmatically from aws console from this link
Then you can try your source code after that.
The following code example shows how to get an item from a DynamoDB table.
// '/path/to/aws-autoloader.php' to import AWS SDKs.
require 'vendor/autoload.php';
use Aws\DynamoDb\DynamoDbClient;
use Aws\Exception\AwsException;
use Aws\DynamoDb\Exception\DynamoDbException;
// Create an SDK class used to share configuration across clients.
$sdk = new Aws\Sdk([
'region' => 'us-west-2',
'version' => 'latest'
]);
// Use an Aws\Sdk class to create the dynamoDbClient object.
$dynamoDbClient = $sdk->createDynamoDb();
try {
$dynamoDbClient->getItem([
'Key' => [
'id' => [
'N' => 1,
],
],
'TableName' => 'products',
]);
} catch (DynamoDbException $e) {
// Catch a DynamoDb-specific exception.
echo $e->getMessage();
} catch (AwsException $e) {
// This catches the more generic AwsException. You can grab information
// from the exception using methods of the exception object.
echo $e->getAwsRequestId() . "\n";
echo $e->getAwsErrorType() . "\n";
echo $e->getAwsErrorCode() . "\n";
// This dumps any modeled response data, if supported by the service
// Specific members can be accessed directly (e.g. $e['MemberName'])
var_dump($e->toArray());
}
Notice that we did not explicitly provide credentials to the client. That’s because the SDK should detect the credentials from environment variables (via AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY), an AWS credentials INI file in your HOME directory, AWS Identity and Access Management (IAM) instance profile credentials, or credential providers.
If we don’t provide a credentials option, the SDK attempts to load credentials from your environment in the following order:
Load credentials from environment variables.
Load credentials from a credentials .ini file.
Load credentials from IAM role.
We can also directly create the service-specific client object like below:
$dynamoDbClient = new DynamoDbClient(
[
'region' => 'us-west-2',
'version' => 'latest',
]
But AWS highly recommended that you use the Sdk class to create clients if you’re using multiple client instances in your application. As per AWS docs:-
The Sdk class automatically uses the same HTTP client for each SDK
client, allowing SDK clients for different services to perform
nonblocking HTTP requests. If the SDK clients don’t use the same
HTTP client, then HTTP requests sent by the SDK client might block
promise orchestration between services.
You can refer to the AWS document pages:-
AWS SDK PHP - BASIC USAGE
AWS SDK PHP - DynamoDB Examples
AWS SDK PHP - Configuration guide
AWS SDK PHP - APIs
I hope this helps.

How to verify if AWS SES API requests are signed using Signature Version 4

An email from Amazon AWS states:
Beginning October 1st, 2020, Amazon SES will only support requests
signed using Signature Version 4.
You can easily identify API requests that use Signature Version 3 by
looking at the request headers. Requests that use the Signature
Version 3 resemble the following example: X-Amzn-Authorization:
AWS3-HTTPS
AWSAccessKeyId=AKIAIOSFODNN7EXAMPLE,Algorithm=HMACSHA256,Signature=lBP67vCvGl
...
I have got "aws/aws-sdk-php" installed through composer.
I'm trying to find out if the request header of SES is Signature Version 3 or 4.
I tried dumping the content of Illuminate\Mail\Events\MessageSent through $event->message->getHeader() which is a Swift_Mime_SimpleHeaderSet Object.
Yet it doesn't include the request version to the SES sdk.
QUESTION:
Could someone please tell me how to dump the outgoing aws ses sdk request so I can see in the header what version is used.
Thank you.
If anyone is interested, finally was able to do it by back tracing the stack.
After sending a mail through a command, I back traced the stack and could see the raw request, which included Authorization: AWS4-HMAC-SHA25, confirming Signature Version 4.
Mail::to($receiver)->send($mailable);
dump(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 50));
Make sure that you have the ses service debug set to true:
config/services.php
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-west-1',
'debug' => true,
],

Google Server-to-Server OAuth2 PHP example not working

I am following this example to get server-to-server access working between my PHP application and Google Cloud API's,
https://developers.google.com/api-client-library/php/auth/service-accounts. In particular, I need to access the Drive API.
When I run the application though I get the following error:
Google_Service_Exception : {
"error": "unauthorized_client",
"error_description": "Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested."
}
Here's what I have done:
Created a GCP project
Added a service account to the project, with domain wide delegation, and a set of keys
Enabled the Google Drive API in the project
In my G Suite account, under 'Manage API client access', I have added the Client ID of my service account, with the permission of https://www.googleapis.com/auth/drive
Have I missed a step?
Here's my code:
putenv('GOOGLE_APPLICATION_CREDENTIALS=my_storage/secure/my-app-service-account.json');
$client = new \Google_Client();
$client->setScopes(\Google_Service_Drive::DRIVE_METADATA_READONLY);
$client->useApplicationDefaultCredentials();
$client->setSubject('my_email#my_domain.com');
$drive = new \Google_Service_Drive($client);
echo $drive->about->get();
The example does not include the setScopes() call, however I was getting a scope-related error without it. (The example is not based on the Drive API, so perhaps it's not required in that case?)
UPDATE: In the IAM settings for the GCP, I added the email address of the service account as a Project Owner, but that made no difference.
I found the problem.
In the setScopes() call above, the value passed needs to be the same as the value given when setting up the client in G Suite, in this case https://www.googleapis.com/auth/drive

Google API PHP error 500

I'm using google vision API in one of my PHP script.
Script works well when I'm executing it through the terminal:
php /var/www/html/my_script.php
But when I want to execute it from my browser I'm getting an error 500:
PHP Fatal error: Uncaught
Google\Cloud\Core\Exception\ServiceException: {\n "error": {\n
"code": 401,\n "message": "Request had invalid authentication
credentials. Expected OAuth 2 access token, login cookie or other
valid authentication credential. See
https://developers.google.com/identity/sign-in/web/devconsole-project.",\n
"status": "UNAUTHENTICATED"\n }\n}\n
I don't get why the error message suggests me to use OAuth 2, I don't need my user to log to his google account.
My code is the following:
namespace Google\Cloud\Vision\VisionClient;
require('vendor/autoload.php');
use Google\Cloud\Vision\VisionClient;
$projectId = 'my_project_id';
$path = 'https://tedconfblog.files.wordpress.com/2012/08/back-to-school.jpg';
$vision = new VisionClient([
'projectId' => $projectId,
]);
$image = $vision->image(file_get_contents($path), ['WEB_DETECTION']);
$annotation = $vision->annotate($image);
$web = $annotation->web();
Generally speaking, you will need to provide a service account keyfile when constructing a Google Cloud client. The exception to this is if you're running on Compute Engine, or if you have Application Default Credentials setup. Since you're seeing authentication errors, neither of those appear to be the case.
To obtain a service account and keyfile, check out the documentation.
Once you have created a service account and downloaded the json keyfile, you can provide it to the client library constructor:
<?php
use Google\Cloud\Vision\VisionClient;
$vision = new VisionClient([
'projectId' => $projectId,
'keyFilePath' => '/path/to/keyfile.json'
]);
Once you provide a valid keyfile, you should be able to make authenticated requests to the Vision API.
To avoid this step, you can setup Application Default Credentials on your server or computer.

Google Storage Incorrect Authorization Header with Amazon S3 PHP SDK v3

I'm in the process of migrating from Amazon S3 to Google Storage and I can't seem to get my credentials to work. Here's some sample code that I put together to test my credentials:
$client = new S3Client([
'credentials' => [
'key' => 'GOOGxxxxxxxxxxxxxxx',
'secret' => 'ZfcOTxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
],
'region' => 'US',
'version' => 'latest',
'endpoint' => 'https://storage.googleapis.com',
]);
try {
$result = $client->putObject(array(
'Bucket' => 'devtest',
'Key' => 'test',
'Body' => 'Hello world'
));
echo $result['ObjectURL'];
} catch (\Aws\S3\Exception\S3Exception $e) {
// The AWS error code (e.g., )
echo $e->getAwsErrorCode() . "\n";
// The bucket couldn't be created
echo $e->getMessage() . "\n";
}
Here's what I get back:
InvalidSecurity Error executing "PutObject" on "https://storage.googleapis.com/devtest/test"; AWS HTTP error: Client error response [url] https://storage.googleapis.com/devtest/test [status code] 403 [reason phrase] Forbidden InvalidSecurity (client): The provided security credentials are not valid. - InvalidSecurityThe provided security credentials are not valid.
Incorrect Authorization header
I've tried googling 100 different combinations of this issue and can't find anything. I have Interoperability enabled, at least I think I do since I don't think I can get the key/secret without it being enabled first. And I have the Google Storage API enabled.
Any help would be greatly appreciated.
Edit: here's the Authentication Header in case that helps:
AWS4-HMAC-SHA256
Credential=GOOGGUxxxxxxxxxxx/20150611/US/s3/aws4_request,
SignedHeaders=host;x-amz-content-sha256;x-amz-date,
Signature=9c7de4xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
I noticed it stays "aws4_request" even when I specify 'signature' => 'v2'. Not sure if that matters.
I took a look at the S3Client code and it doesn't use the 'signature' config key as far as I can tell. The only thing I found was 'signature_version' which when set to v2, I get this error:
Unable to resolve a signature for v2/s3/US. Valid signature versions include v4 and anonymous.
I'm using Laravel 5.1 with composer package aws/aws-sdk-php version 3.0.3
Any ideas?
S3 only supports v4 signatures, and this requirement is enforced by the PHP SDK. It seems that Google Cloud Storage only supports v2 signing, so you wouldn't be able to use the same library to talk to both. Google does provide their own PHP SDK, which might make talking to Cloud Storage a bit easier.

Categories