I currently have a setup where in my Laravel app where there is a MySQL table of documents that store metadata and links to objects stored in an S3 bucket. I have AdministratorAccess credentials for an IAM user stored in my .env file.

I followed this tutorial in order to set up the file upload as the files to be uploaded are very large.

The direct to S3 file upload form looks like:

<form method="post" action="https://{{ config('filesystems.disks.s3.bucket') }}.s3.amazonaws.com" enctype="multipart/form-data"> <input type="hidden" name="AWSAccessKeyId" value="{{ config('filesystems.disks.s3.key') }}"> <input type="hidden" name="acl" value="private"> <input type="hidden" name="key" value="{{ $document->user_id }}/{{ $document->id }}_${filename}"> <input type="hidden" name="policy" value="{{ $policy }}"> <input type="hidden" name="success_action_redirect" value="{{ url('/document_upload') }}"> <input type="hidden" name="signature" value="{{ $signature }}"> <input type="file" name="file"> <button type="submit" class="btn btn-success">Upload document</button> </form>

In my Laravel app a document belongs to a user. I prefix the file upload with a folder for the user_id and prefix the file name with the document's id. I would like to have users in my Laravel app only to have access to files in their user id's folder.

Once the file is uploaded, it redirects to this controller action where I store the data from S3 in my MySQL documents table:

/** * Upload file to be attached to document (redirected after AWS upload) * * @return \Illuminate\Http\Response */ public function document_upload(Request $request){ // check to make sure user is an admin $request->user()->authorizeRoles('admin'); // bucket, key, etag $awsResponse = request()->all(); // documents stored as: {{ $document->user_id }}/{{ $document->id }}_${filename} $filename = explode("/", $awsResponse['key'])[1]; $document_id = explode("_", $filename)[0]; // Lookup document and add fields $document = Document::find($document_id); $document['file_path'] = $filename; $document['aws_key'] = $awsResponse['key']; $document['aws_bucket'] = $awsResponse['bucket']; $document['etag'] = $awsResponse['etag']; // set form fields return view('admin.document', compact('document', 'awsResponse')); }

Only admins can upload files. The first line checks the authorization status then it adds the information from the S3 upload to the document table.

When I rerender the documents page I would like to display the file but am getting access denied. This is the blade template I'm using that shows access denied error:

<embed src="https://s3-us-west-2.amazonaws.com/myBucketName/{{ $document->user_id}}/{{ $document->file_path }}" style="width:800px; height:800px;" frameborder="0"> <a target='_blank' href='https://s3-us-west-2.amazonaws.com/myBucketName/{{ $document->user_id}}/{{ $document->file_path }}'>Download Link</a>

What sort of bucket policies or authentication system do I need to set in order to display the files from my bucket on the page? I have an authorization system where users can log in and users have roles. Users with the administrator role can upload files. Users with the client role can only view files in the folder that has a name equal to their user id.

How can I allow users that have signed into my Laravel application the ability to view files?