Manage S3 Buckets with Laravel & PHP Upload, Create, Configure Policies, IAM Users, Bucket Policy Permissions
Uploading files to an Amazon S3 bucket is a common task in modern web development, allowing developers to store and manage large amounts of data securely in the cloud. Amazon S3 (Simple Storage Service) provides a reliable and scalable solution for storing files, making it an ideal choice for various applications, including web hosting, data backup, and content delivery. To upload files to an S3 bucket programmatically, developers can leverage the AWS SDK (Software Development Kit), which provides APIs for interacting with AWS services from their applications. Here's a general overview of the process:
Firstly, developers need to set up an AWS account and create an S3 bucket using the AWS Management Console or programmatically using AWS CLI (Command Line Interface) or SDK. Once the S3 bucket is created, developers can integrate the AWS SDK into their application. For a JavaScript-based application, such as a web application or a Node.js server, they can use the AWS SDK for JavaScript/Node.js. Next, developers need to configure the AWS SDK with their AWS credentials and specify the region where the S3 bucket is located. This typically involves creating an AWS IAM (Identity and Access Management) user with appropriate permissions for accessing the S3 bucket and generating access keys. With the AWS SDK configured, developers can use the provided APIs to upload files to the S3 bucket. This involves specifying the file to be uploaded, the destination bucket, and the desired key (file path) within the bucket. The SDK handles the process of uploading the file to S3, including handling authentication, encryption, and error handling. Once the upload is complete, the file is stored securely in the S3 bucket and can be accessed and managed using the AWS Management Console or programmatically using the SDK.
If you have a web application and need to integrate and configure it for , to upload your files on Amazon S3 Bucket using PHP OR any frame work like Laravel etc. You have to create S3 Bucket then you need to Add User , Add Policy using AWS Policy Generator and then you need to configure Cross-Origin Resource Sharing (CORS). So after configuration of all things above , you will be able to upload file there on s3 bucket using Laravel or you can test a simple file upload , image upload if you don't want to use Laravel or any other PHP framework. First logged in to your AWS Account on web and do the steps below:
1. Creating S3 Bucket
Just go to amazon console and login and find the Storage under it click on S3 , You can see below screen fill it up there Bucket Name is of your choice, AWS Region select your Region , Block Public Access settings for this bucket uncheck "Block public access to buckets and objects granted through new public bucket or access point policies" , Bucket Versioning You can enable it or disable it based on your requirement as per little information given below is "You can easily recover from both unintended user actions and application failures." matters enable it if you want this. Tags again a little information given there is "Track storage cost or other criteria by tagging your bucket" I needed this as well as Bucket Versioning so enable for my project. you can also configure and change this option latter.Some time what happened you know we Configure basic things and after successful TEST We can enable change other option configuration.
If you want only a TEST then when you are creating a s3 bucket just on this section "Block Public Access settings for this bucket" change and rest of things will be default. Click on create bucket your bucket will be created and listed there.
2. Add User
Just click Services on top navigation then find "Security, Identity, & Compliance" then IAM click on it then in side bar panel click on Users then see there and click on Add users. there will be 5 steps just click on Next then on last steps click on create user , These keys needed in PHP Environment for uploading files , images , document to s3 bucket.3. Bucket Policy
Click on bucket you created and then go to Permissions Tab scroll down you will see Bucket policy , just click on edit , there you will see a Policy generator click on it , for generating policy Select Type of Policy as "S3 Bucket Policy" and in Actions select DeleteObject, GetBucketLocation, GetObject, ListBucket , PutObject, Amazon Resource Name (ARN) put this arn:aws:s3:::lamybuckettest,arn:aws:s3:::lamybuckettest/* with comma separated and replace lamybuckettest with your bucket you created. Now click on generate policy and just copy it and paste it to Bucket Policy.{ "Id": "Policy1628443556664", "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt1628442118799", "Action": [ "s3:DeleteObject", "s3:GetBucketLocation", "s3:GetObject", "s3:ListBucket", "s3:PutObject" ], "Effect": "Allow", "Resource": [ "arn:aws:s3:::lamybuckettest", "arn:aws:s3:::lamybuckettest/*" ], "Principal": "*" } ] }
4. Edit Cross-origin resource sharing (CORS)
Just in Permission Tab scroll down and you will see Cross-origin resource sharing (CORS) edit and place below json code there and save changes.[ { "AllowedHeaders": [ "Authorization" ], "AllowedMethods": [ "PUT", "POST", "GET" ], "AllowedOrigins": [ "*" ], "MaxAgeSeconds": 3000 } ]
5. Uploading Image to Amazon s3 with HTML
We need a html code for browsing file , Do this in your directory www or htdoc --> S3upload(Folder Create)--> index.php (File Create) (Copy below code) , S3upload(Folder Create)--> upload.php (File Create)<!DOCTYPE html> <html> <body> <form action="upload.php" method="post" enctype="multipart/form-data"> Select image to upload: <input type="file" name="userfile" id="userfile"> <input type="submit" value="Upload Image" name="submit"> </form> </body> </html>
6. Add AWS SDK via Composer
go to command line and then go to folder (s3upload) by cd and run the below command to install library aws-sdk-php , you can read Amazon Aws Read.composer require aws/aws-sdk-php
7. Upload File To Amazon S3 Php
You can place this below code and put in upload.php file and make sure to place your Bucket Name , region as per your aws ec2 instance. Because i am testing s3 upload from my localhost so http verify is false.<?php require './vendor/autoload.php'; use Aws\S3\S3Client; use Aws\S3\Exception\S3Exception; $bucketName = 'BUCKENAME'; $IAM_KEY = 'KEY'; $IAM_SECRET = 'SECREATKEY'; try { $s3 = S3Client::factory( array( 'credentials' => array( 'key' => $IAM_KEY, 'secret' => $IAM_SECRET ), 'version' => 'latest', 'region' => 'youregion', 'http' => [ 'verify' => false ] ) ); } catch (Exception $e) { die("Error: " . $e->getMessage()); } $uload_file=$_FILES["userfile"]; $fileURL = $uload_file['name']; $tempFilePath=$uload_file['tmp_name']; $keyName = 'userprofile/' . basename($fileURL); $pathInS3 = 'https://s3.us-east-2.amazonaws.com/' . $bucketName . '/' . $keyName; try { $fileContents = file_get_contents($fileURL); $s3->putObject( array( 'Bucket'=>$bucketName, 'Key' => $keyName, 'SourceFile' => $tempFilePath, 'StorageClass' => 'REDUCED_REDUNDANCY' ) ); } catch (S3Exception $e) { die('Error:' . $e->getMessage()); } catch (Exception $e) { die('Error:' . $e->getMessage()); }
8. Uploading file to Amazon S3 Laravel
Before uploading file documents to Amazon S3 , we need to configure AWS Settings in laravel , kindly add below array in config\filesystems.php inside disks array .'s3' => [ 'driver' => 's3', 'key' => env('AWS_ACCESS_KEY_ID'), 'secret' => env('AWS_SECRET_ACCESS_KEY'), 'region' => env('AWS_DEFAULT_REGION'), 'bucket' => env('AWS_BUCKET'), 'url' => env('AWS_URL'), 'endpoint' => env('AWS_ENDPOINT'), 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', true), 'scheme' =>'http', ]
Add Below Code to .env configuration file
AWS_ACCESS_KEY_ID=Your_Access_Key AWS_SECRET_ACCESS_KEY=Your_Secret_Key AWS_DEFAULT_REGION=Your_Resion AWS_BUCKET=BucketName AWS_USE_PATH_STYLE_ENDPOINT=false
Your controller code goes like below
<?php use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Storage; class ImageUploadController extends Controller { public function index(){ return view('front.image_upload'); } /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function upload_post_image(Request $request) { $request->validate([ 'image' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048', ]); if($request->hasfile('image')){ $file = $request->file('image'); $imageName=time().$file->getClientOriginalName(); $filePath = 'images/' . $imageName; Storage::disk('s3')->put($filePath, file_get_contents($file)); return back()->with('success','You have successfully upload image.'); } } }
Your laravel view will goes like below , You can make it proper , this is just a example for understanding. also add route to your web , so that you can access and process form submittion.
<html lang="en"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <div class="container"> <div class="row"> </div> <form action="{{ route('upload.post.image') }}" method="POST" enctype="multipart/form-data"> @csrf <div class="row"> <div class="col-md-6"> <input type="file" name="image" class="form-control"> </div> <div class="col-md-6"> <button type="submit" class="btn btn-success">Save To S3</button> </div> </div> </form> </div> </body> </html>