Hi I am using aws SDK Version 3 for php to upload files on s3
I need to get rid of credentials file ( .aws/credentials) because it's causing issues on my production server,
The hard coded credentials method isn't working in my code. link pasted below.
https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html#hardcoded-credentials
kindly provide a valid and working solution how to use hard coded credentials.
please note if i use credential file everything works OK. so the problem is with credentials code.
here is my code when I initiate my s3 object
$s3Client = new S3Client([
'profile' => 'default',
'region' => 'us-west-2',
'version' => '2006-03-01',
'scheme' => 'http',
'credentials'=>[
'key' => KEY,
'secret' => SECRET
]
]);
You just need to remove the 'profile' => 'default', line, which has the effect of overriding your hard-coded credentials.
I've been dealing with your same problem with much frustration today, and finally solved it. See related answer here for the same problem on a different Amazon service.
per AWS documentation, https://docs.aws.amazon.com/aws-sdk-php/v2/guide/credentials.html
If you do not provide credentials to a client object at the time of
its instantiation (e.g., via the client's factory method or via a
service builder configuration), the SDK will attempt to find
credentials in your environment when you call your first operation.
The SDK will use the $_SERVER superglobal and/or getenv() function to
look for the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment
variables. These credentials are referred to as environment
credentials.
V3 doc here https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
In my case I am using an IAM role in the machines which host the app, it is easier to manage permissions from IAM dashboard and you will avoid hardcoded or config file with credentials.
Related
I'm getting a "Could not construct ApplicationDefaultCredentials" from Google Recaptcha Enterprise, but only on our remote server. I've tried everything I can think of to isolate the issue, but I've had no luck.
I have two Recaptcha Enterprise keys: One for testing, and one for prod.
The testing key works fine on localhost. I've tried both the testing and prod key on our staging server, but I keep getting the same error.
Could not construct ApplicationDefaultCredentials
Things I've checked:
The key is successfully requesting tokens (I can see them in the form)
The service account .json credentials are being picked up correctly (I've tried outputting the contents to ensure they can be read)
The domains are correctly configured and allowed (Google helpfully lets you know if this isn't the case)
The Project ID is also correctly being picked up and sent
Basically all the values are present (project ID, site ID, service account details) and the domain is allowed, but as soon as it's on the remote staging server, it is failing to create credentials.
I'm struggling to figure out what the difference could be.
public static function createRecaptchaAssessment(
string $siteKey, // Present
string $token, // Present
string $projectId // Present
): Assessment {
$options = [
'keyFile' => config('services.google.app_credentials'), // Present
'projectID' => $projectId
];
$client = new RecaptchaEnterpriseServiceClient($options); // <-- Throws exception for ApplicationDefaultCredentials not being able to be created
...
Things to consider: The staging server is hosted on an elasticbeanstalk.com subdomain, and the site is password protected with .htpasswd. I know sometimes elasticbeanstalk.com is blacklisted because it is a blanket domain, but we're only specifying the subdomain and there's no "This domain is not allowed" message from Google. And there shouldn't be any inbound connections being blocked by .htapasswd that I'm aware of.
I've tried creating a new Service Account, just incase there was something configured incorrectly (it has Recaptcha Enterprise Agent permissions) but nothing changed.
Any ideas on how else I could debug this would be gratefully appreciated. (Note: This is a PHP/Laravel 9 project hosted on AWS Elastic Beanstalk, but I don't think that's a factor.)
Key takeaway: The ApplicationDefaultCredentials error is almost certainly related to the Service Account .json not being picked up by your application.
Full version: So apparently I took some poor advice from another SO answer which suggested you could pass the path to the Service Account credentials .json file through the following array:
$options = [
'keyFile' => config('services.app_credentials'), // DON'T DO THIS
'projectID' => $projectId
];
I spent a long time looking through the Google library only to discover that neither array keys are used. Actually what happens is this:
If the library isn't passed a path to the Service Account credentials .json file, it then looks for an environment variable called GOOGLE_APPLICATION_CREDENTIALS.
If you have this ENV and your environment supports it, that's actually what it is going on. (Which is why you might find that it works locally, but not remotely, as I did.)
When you deploy Laravel remotely, all the .env variables are cached and so not available through getenv()... meaning the library is not able to find GOOGLE_APPLICATION_CREDENTIALS even if you have it included in your .env.
The solution is to add the path through an array key credentials:
$options = [
'credentials' => config('services.app_credentials')
];
$client = new RecaptchaEnterpriseServiceClient($options);
Now it works perfectly.
I would like to use SNS/SQS in my PHP application, that is running on an EC2 instance.
I was able to find the guide about credentials for the AWS SDK for PHP Version 3, but I still have no idea how to simply use the IAM Role that is associated with my EC2 instance, my app is running on.
This is what I tried:
$SnSclient = new SnsClient([
'profile' => 'default',
'region' => 'eu-central-1',
'version' => '2010-03-31',
'credentials' => \Aws\Credentials\CredentialProvider::defaultProvider()
]);
But I get this error:
PHP Fatal error: Uncaught Aws\Exception\CredentialsException: Cannot read credentials from /home/ec2-user/.aws/credentials in phar:///var/www/html/aws.phar/Aws/Credentials/CredentialProvider.php:874
I would like to avoid uploading my pem file to the instance, since it is already running in AWS, as far as I know it should be able to use it's IAM role
The 'profile' => 'default', line had to be removed, as suggested in this answer
It does not seem to be well documented, but if you are using the IAM Role of the instance, then no profile or credentials attributes are necessary
I just updated my Laravel application from 5.8.x to 6.18.x. I also updated the ENV name declaration to reflect the new Laravel pattern.
AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY and AWS_DEFAULT_REGION.
I set AWS_DEFAULT_REGION to eu-west-1 since I am using eu-west-1.amazonses.com in the SES setup.
But when I try to send an email now, I get: Error executing "SendRawEmail" on "https://email.eu-central-1.amazonaws.com" even though eu-central-1 is nowhere declared inside my app. I've been trying to wrap my head around this for a while now, but cannot find a solution.
Also, it seems like AWS wants me to verify the to address, which is even more confusing. I've been out of the sandbox for over 2 years and on the live server with the older Laravel instance the mail still works just fine.
I have no actual code, since this is just stuff in my ENV file and this inside my config/services.php file:
'ses' => [
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION'),
],
I really don't know what else I could check.
I suggest you set the region directly on config/services.php and see if it works. If it works, I would check why the values set on the environment file is not passing down the chain.
Hope this helps.
Thanks for all your suggestions. The problem was actually not AWS related. After the upgrade from 5.8 to 6.x the old .env file was still used. So any changes I did to the .env file were not used. I don't know why though, as I cleared all caches and config files after the upgrade. But it's working again now.
I am trying to send SNS messeges to android through web api.
Downloaded and installed the SDK from http://aws.amazon.com/developers/getting-started/php/
Got following error while running sample.php:
Fatal error: Uncaught exception 'Aws\Common\Exception\InstanceProfileCredentialsException' with message 'Error retrieving credentials from the instance profile metadata server. When you are not running inside of Amazon EC2, you must provide your AWS access key ID and secret access key in the "key" and "secret" options when creating a client or provide an instantiated Aws\Common\Credentials\CredentialsInterface object. ([curl] 28: Connection timed out after 5016 milliseconds [url] http://169.254.169.254/latest/meta-data/iam/security-credentials/)' in C:\xampp\htdocs\aws-php\vendor\aws\aws-sdk-php\src\Aws\Common\InstanceMetadata\InstanceMetadataClient.php:85 Stack trace: #0 C:\xampp\htdocs\aws-php\vendor\aws\aws-sdk-php\src\Aws\Common\Credentials\RefreshableInstanceProfileCredentials.php(52): Aws\Common\InstanceMetadata\InstanceMetadataClient->getInstanceProfileCredentials() #1 C:\xampp\htdocs\aws-php\vendor\aws\aws-sdk-php\src\Aws\Common\Credentials\AbstractRefreshableCredentials.php(54): Aws\Common\Credentials\Refreshable in C:\xampp\htdocs\aws-php\vendor\aws\aws-sdk-php\src\Aws\Common\InstanceMetadata\InstanceMetadataClient.php on line 85
A little guidance on this topic will help me a lot
In my case, I was using
return DynamoDbClient::factory(array(
'version' => 'latest',
'region' => AWS_REGION,
'key' => AWS_KEY,
'secret' => AWS_SECRET
));
which used to be ok with aws/aws-sdk-php version 2.8.5 , but when composer automatically installed version 3.2.0, I got the error above. The problem is simply that I should've changed the way I made the call to
return DynamoDbClient::factory(array(
'version' => 'latest',
'region' => AWS_REGION,
'credentials' => array(
'key' => AWS_KEY,
'secret' => AWS_SECRET,
)
));
as documented here. Without changing the call, the apache php was falling back to looking for the ~/.aws/credentials file using the HOME environment variable, which was empty. You can check its value by running php -r 'var_dump(getenv("HOME"));'.
This is a related post
In my case I had to use hard-coded credentials
$s3Client = new S3Client([
'region' => REGION,
'version' => '2006-03-01',
'credentials' => [
'key' => S3_KEY,
'secret' => S3_SECRETE,
],
]);
See more details here:
You have to place the .aws/credentials file with your configuration in the home directory of the web service *usually /var/www) not in the home directory of the logged in user.
You can find what home directory you web service is using by running echo getenv('HOME'); in a php file on your server.
I was trying to use a credentials file and got the same error, this guy on github pretty much nailed it:
The credentials file should be in ini format but not have a .ini extension. It should have a 'default' section defined with your key and secret:
$ less ~/.aws/credentials
[default]
aws_access_key_id = key
aws_secret_access_key = secret
If you specified other section name instead of default, just add a profile key to the S3Client parameters:
[example]
aws_access_key_id = key
aws_secret_access_key = secret
$s3Client = new \Aws\S3\S3Client([
'version' => '2006-03-01',
'region' => $yourPreferredRegion,
'profile' => 'example',
]);
Using a credentials file or environment variables is the recommended way of providing credentials on your own server
And #Anti 's answer also helped me alot!
If you prefer the hard coded way, just follow #shadi 's answer.
assuming that the server is located on AWS EC2 (probably the same for ECS and elastic beanstalk) the "correct" way to handle this issue is not to store credentials at all.
instead, do this:
create an IAM role (https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)
add relevant permissions to the role policy (in this case, send SNS msg)
assign the role to the EC2 instance (instance settings => Attach/Replace IAM Role)
this way you don't leave any sensitive data in your code.
Here are the steps:
Type cd ~
By this you will go into the home directory.
mkdir .aws
sudo vi .aws/credentials
Write following lines and save the file.
[default]
aws_access_key_id = Your AWS Access Key
aws_secret_access_key = Your AWS Secret Access Key
If it is laravel and aws/aws-sdk-php-laravel sdk then after configuring all step and defining key in .env file
you have to drop config cache and rebuild it by following commands.
php artisan config:cache;
composer dump-autoload;
This might be because the config file hasn't been published.
Be sure to publish the config file:
php artisan vendor:publish --provider="Aws\Laravel\AwsServiceProvider"
To test this is the issue, just clear the config.
php artisan config:clear
If it works with the cache cleared, then this will be the issue.
You can try these lines:
$credentials = new Aws\Credentials\Credentials('key' , 'secret-key');
$s3 = new S3Client(['version' => 'latest','region' => 'ap-south-1','credentials'=>$credentials]);
I am currently using AWS Elastic Beanstalk to launch a LAMP environment. Due to Elastic Beanstalk being an multiple instance environment, $_SESSION is not configured to work correctly and it is recommended to use DynamoDB Session Handler. This works fine for me with the following code inserted prior to session_start();
require 'vendor/autoload.php';
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Session\SessionHandler;
$dynamoDb = DynamoDbClient::factory(array(
'key' => 'XXXX',
'secret' => 'XXXX',
'region' => 'us-east-1'
));
$sessionHandler = SessionHandler::factory(array(
'dynamodb_client' => $dynamoDb,
'table_name' => 'sessions',
));
$sessionHandler->register();
But, this does not work app wide and is causing issues getting phpMyAdmin up and running. How do I make this work app wide?
AFAIK, there is no way to configure a custom session handler from a php.ini, and to use the DynamoDB Session Handler, you must bootstrap it somehow. For an app with multiple entry points, this presents a challenge. One idea you could try is using the auto_prepend_file INI setting to run the bootstrap code.