I am using the Amazon API and get this error while updating my stock from my database to Amazon website:
Caught Exception: Internal Error
Response Status Code: 0
Error Code:
Error Type:
Request ID:
XML:
I read this thread (amazonsellercommunity . com/forums/thread.jspa?messageID=2194823) and then get the error explanation:
<Error><Type>Sender</Type><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.</Message><Detail/></Error>
So I thought my MARKETPLACE_ID, MERCHANT_ID, AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY could be wrong. But I checked and these informations are correct.
Actually, I don't understand why this error happens... Before, it worked perfectly and since a couple of days it just crash. And I don't change anything in my code. Strange, isn't it?
Edit :
Here is my section code for signature.
define ('DATE_FORMAT', 'Y-m-d\TH:i:s\Z');
define('AWS_ACCESS_KEY_ID', 'ABC...'); // My AWS Access Key Id (20 characters)
define('AWS_SECRET_ACCESS_KEY', 'ABCDEF...'); // My AWS Secret Access Key (40 characters)
define('APPLICATION_NAME', 'MyCompany_AmazonMWS');
define('APPLICATION_VERSION', '0.0.1');
define ('MERCHANT_ID', 'XXXXXXX'); // My Merchant ID
define ('MARKETPLACE_ID', 'XXXXXXX'); // My Marketplace ID
$config = array (
'ServiceURL' => "https://mws.amazonservices.fr",
'ProxyHost' => null,
'ProxyPort' => -1,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebService_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
$config,
APPLICATION_NAME,
APPLICATION_VERSION
);
$parameters = array (
'Marketplace' => MARKETPLACE_ID,
'Merchant' => MERCHANT_ID,
'FeedType' => '_POST_INVENTORY_AVAILABILITY_DATA_',
'FeedContent' => $feedHandle,
'PurgeAndReplace' => false,
'ContentMd5' => base64_encode(md5(stream_get_contents($feedHandle), true)),
);
// and then I do this:
$request = new MarketplaceWebService_Model_SubmitFeedRequest($parameters);
invokeSubmitFeed($service, $request);
If you want to see some parts of my code, just ask.
If I recall correctly, the authentication mechanism for Amazon APIs is sensitive to the current date/time on your machine (which is used in the process of signing the request). Check to see if your date/time is set correctly.
For me it was just an error with my web app passing url escaped strings. The special characters weren't like by amazon and this (not so useful) error came up. Make sure your file names have no url escaped characters.
I solved it (on Ubuntu 14.04 Server) using ntpdate:
First make sure it is installed:
apt-get install ntpdate
And then execute:
ntpdate ntp.ubuntu.com
Related
Summary:
I tried to obtain AWS Cognito User name (OAuth2 from Google) with Perl module Paws::CognitoIdp::GetUser but I failed the code:
my $GetUserResponse = $cognito_idp->GetUser(
AccessToken => 'MyTokenModelType',
);
with the error Invalid Access Token.
Environment
I am developing Web service with following environment:
AWS + EC2 + Ubuntu 20.04 + nginx 1.20.1 + Perl 5.30.0
Using Cognito with Google OAuth2.0
What I can do now
When you access my Web service, Sign In with Google button will appear. If you click it, you can run my Perl CGI script.
What I cannot do now
I want to obtain your Google user name and mail address, but I cannot.
What I did
I wrote the following code:
my $cognito_idp = Paws->service('CognitoIdp',
region => "ap-northeast-1",
max_attempts => 3,
);
my $GetUserResponse = $cognito_idp->GetUser(
AccessToken => 'MyTokenModelType',
);
my $uname = $GetUserResponse->Username;
Then...
When I access my Web service, it failed with the Software error:
Software error:
Invalid Access Token
Trace begun at /usr/local/share/perl/5.30.0/Paws/Net/JsonResponse.pm line 22
Paws::Net::JsonResponse::process('Paws::Net::JsonResponse=HASH(0x56495fb33d78)', 'Paws::CognitoIdp::GetUser=HASH(0x56495fb41fd0)', 'Paws::Net::APIResponse=HASH(0x56495fde6f38)') called at /usr/local/share/perl/5.30.0/Paws/Net/Caller.pm line 46
Paws::Net::Caller::caller_to_response('Paws::Net::Caller=HASH(0x56495da09a38)', 'Paws::CognitoIdp=HASH(0x56495e05da48)', 'Paws::CognitoIdp::GetUser=HASH(0x56495fb41fd0)', 'Paws::Net::APIResponse=HASH(0x56495fde6f38)') called at /usr/local/share/perl/5.30.0/Paws/Net/RetryCallerRole.pm line 19
Paws::Net::RetryCallerRole::do_call('Paws::Net::Caller=HASH(0x56495da09a38)', 'Paws::CognitoIdp=HASH(0x56495e05da48)', 'Paws::CognitoIdp::GetUser=HASH(0x56495fb41fd0)') called at /usr/local/share/perl/5.30.0/Paws/CognitoIdp.pm line 331
Paws::CognitoIdp::GetUser('Paws::CognitoIdp=HASH(0x56495e05da48)', 'AccessToken', 'MyTokenModelType') called at /DocumentRoot/index.cgi line 16
For help, please send mail to this site's webmaster, giving this error message and the time and date of the error.
Maybe...
I referred following to the documentation
Maybe 'MyTokenModelType' is just the placeholder and I should specify the correct code.
But I don't know how I can make it.
In addition, I want to know how can I obtain not only user name but also user email address.
(Additional Info 2021-11-12)
Thanks to the comment, I read the article:
How to generate access token for an AWS Cognito user?
and I hacked AWS CLI command but I have not got the answer yet.
I think I got to do $ aws connito-idp initiate-auth but I cannot find what arguments I should pass.
In the AWS => Cognito => Users and groups menu, I see the entry of a user of my Web app.
Username: google_??????????
Enabled: Enabled
Account status: EXTERNAL_PROVIDER
Email: (users_email)
I changed my code like this for the experiment to find what information my Web app has.
use Data::Dumper;
my $cognito_idp = Paws->service('CognitoIdp',
region => "ap-northeast-1",
max_attempts => 3,
);
# my $GetUserResponse = $cognito_idp->GetUser(
# AccessToken => 'MyTokenModelType',
# );
# my $uname = $GetUserResponse->Username;
print "Content-type: text/html\n\n\n";
print '<!DOCTYPE html>';
print '<html><pre>';
print Dumper $cognito_idp;
print '</pre></html>';
and I see the contents of $cognito_idp like this:
$VAR1 = bless( {
'_region_for_signature' => 'ap-northeast-1',
...
'credentials' => bless( {
...
'selected_provider' => bless( {
'expiration' => 1636712506,
'actual_creds' => {
'Type' => 'AWS-HMAC',
'SecretAccessKey' => '??????????????',
'Code' => 'Success',
'AccessKeyId' => '???????????????',
'LastUpdated' => '2021-11-12T03:54:16Z',
'Token' => '?????????????????????????????????????',
'Expiration' => '2021-11-12T10:21:46Z'
},
...
I hope I could get the information of the user from the data above.
My question is, how I can specify the MyTokenModelType value of the code:
my $GetUserResponse = $cognito_idp->GetUser(
AccessToken => 'MyTokenModelType',
);
Still I want your info.
Thanks again.
I'm trying to import existing users from another application into Google Cloud Identity Platform using passwords that were hashed using PHP's crypt function with an MD5 output.
This is an example of the hashed password being used in PHP:
$hashed_password = '$1$AT$JGYIRSP7xIYmg1XSoJmvB1';
$user_input = 'test123';
if (hash_equals($hashed_password, crypt($user_input, $hashed_password))) {
echo "Password verified!";
}
I've tried all sorts of combinations for importing the user and their password, but no combination seems to work. This is the NodeJS import script I'm using:
var admin = require('firebase-admin');
var app = admin.initializeApp({
credential: admin.credential.applicationDefault()
});
admin
.auth()
.importUsers(
[
{
uid: '31',
email: 'user31#test.test',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('$1$AT$JGYIRSP7xIYmg1XSoJmvB1'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('$1$AT$'),
},
],
{
hash: {
algorithm: 'MD5',
rounds: 0,
},
}
)
.then((results) => {
console.log(results);
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
As mentioned above, I've tried just about every combination of hash and passwordSalt I could think of. I've tried:
passing no passwordSalt
passing a passwordSalt of AT
passing a passwordSalt of AT$
passing a passwordSalt of $AT
passing a passwordSalt of $AT$
all of the above but with a hash algorithm of BCRYPT
I can see the user getting imported. If I change the hash to something like a regular MD5 hash, I'm able to authenticate as that user, so I know the import process is working correctly.
Does GCP Identity Platform simply not support these hashes? Am I passing the salt incorrectly or passing an incorrect number of rounds? Am I passing the wrong hash algorithm? I'm a little surprised, as I would've thought passwords hashed using PHP's crypt function would've been supported.
4 points:
1.- You are mentioning that you are trying to import existing users and their passwords from another application into Google Cloud Identity Platform. Also, you mentioned that you are using a NodeJS import script focused on MD5. Based on that, and using the same official GCP documentation that you quoted Migrating users from an existing app vs the NodeJS’s script you posted, it seems that you didn’t use the code sample that is posted in that documentation, exactly in the way it should be used, unless that you are the owner of the domain "#test.test":
getAuth()
.importUsers(
[
{
uid: 'some-uid',
email: 'user#example.com',
// Must be provided in a byte buffer.
passwordHash: Buffer.from('password-hash'),
// Must be provided in a byte buffer.
passwordSalt: Buffer.from('salt'),
},
],
{
hash: {
algorithm: 'PBKDF2_SHA256',
rounds: 100000,
},
}
)
.then((results) => {
results.errors.forEach((indexedError) => {
console.log(`Error importing user ${indexedError.index}`);
});
})
.catch((error) => {
console.log('Error importing users :', error);
});
2.- Are we sure you have the required admin rights or role over IAM in your GCP’s Organization? You can use the following official GCP documentation for understanding roles Understanding roles
3.- How are you figuring out that it is not working? Are you facing any of the following errors? Error codes. Is there any particular behavior after the importing process finishes or any log that you can share here editing your original post? Or is it only because you see that once the users are imported to IAM, they are not able to authenticate?
4.- I suggest you by now to follow (Method: users.insert) as stated here Method: users.insert first, this way you are going to review the hash formats that are supported. Finally, you need to do this test with the domains that you have verified in Cloud Identity.
is there anyway to dynamically generate the response for the Amazon Product API with using just a URL string?
I see there are PHP and C# libraries but I am just trying to browse to a URL and see the response. I noticed one of the required fields of the URL is a timestamp which makes this tricky. The following page helped to generate the URLs but I can't seem to find a way to do it dynamically?
http://associates-amazon.s3.amazonaws.com/scratchpad/index.html
Thanks!
This is the dynamic search for amazon product
Download aws_signed_request.php from this url
include('aws_signed_request.php');
$public_key = 'xxxxxxxx';
$private_key = 'xxxxxxxxxx';
$associate_tag = 'xxxxxx';
$keywords= 'PHP';
$search_index = 'Books';
// generate signed URL
$request = aws_signed_request('com', array(
'Operation' => 'ItemSearch',
'Keywords' => "Php Books",
"SearchIndex" => "Books",
"Count" => '24',
'ResponseGroup' => 'Large,EditorialReview'), $public_key, $private_key, $associate_tag);
// do request (you could also use curl etc.)
$response = #file_get_contents($request);
Documentation URL HERE
I'm not sure I totally understand your question, but I think the answer is "the data in the Amazon product API is only available via 'signed' URLs". That way, Amazon can track abuse, etc back to the source (i.e. the signer).
If it were possible to get the data with a "static" URL, then you could post that URL all over the Internet and anyone could get the data without signing up with Amazon. It's their data, and they have rules on it's use, so that wouldn't fly with them.
That said, you can usually create URLs with a timestamp in the future (months or even years). But you would still be responsible for it's use/abuse.
AWS API GetMatchingProductForId is expected to return a list of "AttributeSets" for the product-id matching the input
However, we are receiving null value for "ItemAttributes".
I am calling the API as mentioned below -
Create an instance of MarketplaceWebServiceProducts class. This class is provided under "com.amazonservices.mws.products" package by AWS in "mws-products-1.0.jar"
Create an instance of Request 'GetMatchingProductForIdRequest ' and set the required parameters for it, as below -
GetMatchingProductForIdRequest request = new GetMatchingProductForIdRequest();
request.setSellerId(merchantId);
request.setIdType("ASIN");
request.setMarketplaceId(marketPlaceId);
IdListType idListType = new IdListType();
idListType.setId(idList);
request.setIdList(idListType);
3.Calling the API using the above created request as below -
response = marketplaceWebServiceProducts.getMatchingProductForId(productRequest);
Received response, HTTP status code is 200 (Success). but getting AttributeSets as null
I am also tested this by setting a hard-coded product ID (ASIN : B007VCRRNS) found from Amazon website.
Answer from Amazon:
Thank you for contacting MWS Support. I have checked with our internal team about this and found that we are no longer exposing Feature data in API. We are just returning it as blank to avoid breaking any existing integration.
$serviceUrl = "https://mws.amazonservices.co.uk/Products/2011-10-01";
$config = array (
'ServiceURL' => $serviceUrl,
'ProxyHost' => null,
'ProxyPort' => -1,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebServiceProducts_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
APPLICATION_NAME,
APPLICATION_VERSION,
$config
);
$request = new MarketplaceWebServiceProducts_Model_GetMatchingProductForIdRequest();
$request->setSellerId(MERCHANT_ID);
$request->setMarketplaceId("A1F83G8C2ARO7P");
$request->setIdType("ASIN");
$idlist = new MarketplaceWebServiceProducts_Model_IdListType();
$idlist->setId("B00BNBA6CC");
$request->SetIdList($idlist);
$response = $service->GetMatchingProductForId($request);
I am trying to implement ec2 API in a project. How do we implement pagination on
ec2-descibe-instances. I send the option as null
$ec2 = new AmazonEC2($key, $secret);
$ec2->set_region('us-east-1');
$allInstances = $ec2->describe_instances(null);
If I have hundreds of instances, rendering all instances might be an issue. So want to lazy load 10 instance at a time. I see python boto having some limits but the php SDK for aws.
Can any one please let me know how we can accomplish?
you should refer to this q How to get list of EC2 instances with Amazon PHP SDK 2?
Add Page parameter to the filter as Page=1, page=2 and so on.
$result = $ec2Client->DescribeInstances(array(
'Filters' => array(
array('Name' => 'instance-type', 'Values' => array('m1.small'),'Page' => 2),
)
));