Is there a way for me to showcase a particular PDF file from an S3 bucket using a custom URL that corresponds to the object's name

Currently, I have a collection of PDFs stored on S3 and am in the process of developing an app that requires me to display these PDFs based on their object names. For instance, there is a PDF named "photosynthesis 1.pdf" located in the biology/ folder, and I need to present this PDF on domain.com/exams/{biology}/{photosynthesis 1.pdf}

I am seeking advice on how to create a system where when a user visits a specific URL, the corresponding PDF is displayed on the site. If this approach is not feasible, I am open to alternative suggestions. Despite my efforts to research solutions, I have been unable to find a working method as I am relatively new to working with S3.

The current solution I am considering involves using dynamic routes in NextJS (13.4 app router) to extract the path from the object name in S3 and then embed the PDF on the website. While I am comfortable with setting up dynamic routes, I am facing challenges when it comes to fetching the PDF from S3.

I attempted to retrieve the PDF by making API calls and sending GET requests to a pre-signed URL. However, this method proved ineffective as pre-signed URLs have expiration limits, and I prefer not to make the bucket public. As my knowledge of S3 is limited, I may be mistaken in my understanding of the processes involved.

Thank you for your help.

Answer №1

If you're looking to restrict access to your bucket, consider making it only publicly accessible through GET requests. This method can be beneficial in certain situations. Simply make your bucket public and implement a Bucket Policy like the one below:

{
  "Version": "2012-10-17",
  "Id": "Policy1679789966659",
  "Statement": [
      {
        "Sid": "Stmt167978995632",
        "Effect": "Allow",
        "Principal": "*",
        "Action": "s3:GetObject",
        "Resource": "arn:aws:s3:::your-bucket-name/*"
      }
   ]
}

Note that all objects within your-bucket-name will become public with this setup. It's suitable for allowing users to bookmark a page (pdf), but not ideal if you need to regulate access to these pdfs based on user authentication.

If you prefer to maintain privacy for your S3 bucket and control access to the pdfs based on user accounts, pre-signed URLs are recommended.

In Node.js, you can direct GET requests to a middleware function to verify whether a user is permitted to view the PDF. For instance, if a user goes to:

domain.com/exams/{biology}/{photosynthesis 1.pdf}

You can pass their userid through the router and validate against the database for authorization. If authorized, utilize the AWS SDK for JavaScript to generate a pre-signed URL and return the GET request response accordingly. Refer to the AWS documentation for instructions on "Generate a presigned URL for GetObject".

The s3 client library provides options for setting the validity duration of pre-signed URLs using the expiresIn attribute. For example, a duration of 1 minute would be:

const url = await getSignedUrl(client, command, { expiresIn: 60 });

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What could be causing the malfunction in the app due to the GraphQL input type?

I encountered a challenge while testing a mutation on an Apollo GraphQL API. Initially, everything was working fine as I utilized individual fields for the mutation type. However, as soon as I replaced these fields with the input type that I had created, a ...

What is the process of using observables in Angular to retrieve a number or variable?

While working on an angular service that calls an API and processes a large amount of data, I encountered an issue. I was trying to count the occurrences of each type in the data and send back that count along with the data itself. However, I found that wh ...

Contact the help desk and receive information that is currently unknown

There are a few issues that I'm struggling to resolve. I am utilizing SwaggerService to fetch data, but the response is coming back as undefined. import {SwaggerService} from '../../services/swagger.service'; export class TestComponent im ...

`Understanding the outcome type by assessing the (potential) attributes with TypeScript`

Here is a detailed example of a problem with some code: type Mapper<T, R> = (data: T) => R; interface Config<T, R> { readonly mapper?: Mapper<T, R>; } function transform<T, R>(config: Config<T, R>, data: T) { return c ...

"Ionic 3: Utilizing the If Statement within the subscribe() Function for Increased Results

I added an if conditional in my subscribe() function where I used return; to break if it meets the condition. However, instead of breaking the entire big function, it only breaks the subscribe() function and continues to execute the navCtrl.push line. How ...

The issue I'm facing with my webpack-build is the exclusive appearance of the "error" that

Hey everyone! I'm currently facing an issue with importing a module called _module_name_ into my React project, specifically a TypeScript project named react-app. The module was actually developed by me and it's published on npm. When trying to i ...

Issue with incremental static generation in version 13 not functioning as expected

Is ISR working for anyone in the NextJS 13 Beta version? I have set revalidate to 15 as follows. export const revalidate = 15; However, even after running `npm run build`, the page still remains a statically generated site (SSG). The symbol is showing u ...

Angular not firing slide.bs.carousel or slid.bs.carousel event for Bootstrap carousel

I've searched high and low with no success. I'm attempting to detect when the carousel transitions to a new slide, whether it's automatically or by user click. Despite my numerous attempts, I have been unable to make this event trigger. I ha ...

What causes observables stream to be cancelled or stopped by my HTTP request?

I am facing an issue with adding a new property called Blobs to each application in an array of applications. I need to make a separate HTTP request to fetch Blobs for each application using the switchMap operator. However, the problem is that only the las ...

What is the best way to create two MUI accordions stacked on top of each other to each occupy 50% of the parent container, with only their contents scrolling

I am looking to create a layout with two React MUI Accordions stacked vertically in a div. Each accordion should expand independently, taking up the available space while leaving the other's label untouched. When both are expanded, they should collect ...

Issues with DropDown and ListBox functionality in Next.js when using TailwindCSS and HeadlessUI

I encountered an issue with the dropdown menu. Whenever I click on it, the dropdown opens and immediately closes again. I set up TailwindCSS and HeadlessUI according to the documentation. I used DropDown component from HeadlessUI docs. Initially, I suspect ...

The Next.js API is experiencing functionality issues on the Netlify platform

My web application built with Next.js is experiencing issues when deployed on Netlify. The API stops working, although it was functioning correctly on Vercel. Every time I make an API call, I receive a 404 error Here is my package.json: { "name&quo ...

Issue with the scoring algorithm using Angular and Spring Boot

Hello, I have created a scoring algorithm to calculate scores, but I encountered an error in "salaireNet". ERROR TypeError: Cannot read properties of null (reading 'salaireNet') at ScoringComponent.calculateScore (scoring.component.ts:33:55) ...

Encountering a tuple type TypeScript error with a spread argument is far too frequent an occurrence

Encountering this error is becoming a frequent occurrence for me, and I am currently unable to resolve it. src/graphics.ts:105:55 - error TS2556: A spread argument must either have a tuple type or be passed to a rest parameter. 105 _queue.forEach((_ ...

Enhance the functionality of 'takeWhile' by incorporating a limit parameter, similar to how 'take' operates

I am attempting to retrieve all pages until either there are no more pages or a certain limit (let's say 10 pages) is reached. If I follow this approach: obs.pipe(expand((page) => { return service.call(page).nextPage; }), take(10), takeWhil ...

Steps to avoid HTML encoding the ' character in Next.js _document.js file

Currently, I am working on integrating VWO into my website by following the steps mentioned here. I have included the VWO script tag within a NextJs Head tag as shown below: <Head> <script type='text/javascript' id='vwoC ...

Guide for using a CSS variable in a dynamic CSS class within a dynamic component

I'm working with library components and running into an issue with CSS when importing the same component multiple times within a parent component with different styles. import "../myCss.css" const CircleComponent = ({size , color}) => { ...

Querying data conditionally with Angular rxjs

I have a json file that contains multiple arrays structured like this: { A[] B[] C[] ... } This is the query I am using: myFunction():void{ this.apiService.getData() .pipe( map((response: any) => response.A), // to access to the &ap ...

Using TypeScript to transform a tuple type into an object

When dealing with a tuple type like: [session: SessionAgent, streamID: string, isScreenShare: boolean, connectionID: string, videoProducerOptions: ProducerOptions | null, connection: AbstractConnectionAgent, appData: string] there is a need to convert it ...

Adjusting the size of the provided image into three variations prior to storing it in the S3 Bucket

I am currently utilizing the Skipper S3 npm module in conjunction with Sails JS to save images into an S3 Bucket. The code I am using to save images into the S3 bucket through Skipper is shown below: req.file('imageName').upload({ saveA ...