Node.js AWS S3 Presigned URL with SignatureMismatch

I am currently working on a NodeJS script to reverse-proxy client requests by creating pre-signed URLs for S3 objects being requested.

For instance, when a user accesses the website at build.localhost:8080, the 'build' subdomain corresponds to a folder where the NodeJS proxy will serve the index.html file located inside the 'build' folder.

The 'build' folder contains all the necessary files generated by running the npm run build command in order to host the static site with the help of the NodeJS script.

Below is the code snippet:


        const express = require('express');
        const httpProxy = require('http-proxy');
        const AWS = require('aws-sdk');

        var credentials = new AWS.SharedIniFileCredentials({profile: 'saml'});
        AWS.config.credentials = credentials;

        const s3 = new AWS.S3();

        function getPreSignedUrl(key){
            const myBucket = 'test-react-bucket-dev';
            const signedUrlExpireSeconds = 60 * 5;
            
            return new Promise((resolve, reject) => {
                s3.getSignedUrl('getObject', {
                    Bucket: myBucket,
                    Key: key,
                    Expires: signedUrlExpireSeconds
                }, (err, url) => {
                    if (err) reject(err);
                    else resolve(url);
                });
            });
        }

        const app = express();
        const PORT = 8080;

        const proxy = httpProxy.createProxyServer();

        app.get('*', async (req, res) => {
            const hostname = req.hostname;
            const subdomain = hostname.split('.')[0];

            let key = subdomain + (req.path === '/' ? '/index.html' : req.path);

            try {
                const resolvesTo = await getPreSignedUrl(key);
                proxy.web(req, res, { target: resolvesTo, changeOrigin: true });
            } catch (error) {
                console.error("Error:", error);
                res.status(500).send("Error proxying the request");
            }
        });

        proxy.on('proxyReq', (proxyReq, req, res) => {
            const url = req.url;
            req.rawHeaders = []
            if (url === '/')
                proxyReq.path += 'index.html';

            console.log(req.rawHeaders)
        });

        app.listen(PORT, () => console.log(`Reverse Proxy Running..${PORT}`));
    

And here's the encountered error:


        <Error class="hidden">
        <link type="text/css" id="dark-mode" rel="stylesheet" href=""/>
        <style type="text/css" id="dark-mode-сustom-style"/>
        <style type="text/css" id="dark-mode-theme-changer-style"/>
        <Code>SignatureDoesNotMatch</Code>
        <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
        <AWSAccessKeyId>ASIAR---REDACTED---EIYB</AWSAccessKeyId>
        <StringToSign>GET 1707814358 x-amz-security-token:FwoGZXIvYXdzEKf//////////wEaDDy3nYkyTaxu1hEt6iLnAcXSYnhu0Oq0K7AeEc/quuBjIyqMfZON6gbHFZ3/ZLi7yDwPtdlKsiacTDSKiav1XuQI1WP+aXePJ+RwgtJesC177Jmfg=/index.html /test-react-bucket-jk/build/index.html</StringToSign>
        <SignatureProvided>mlC4fkhNSMavJk8R45i6T+QRBr8=</SignatureProvided>
        <StringToSignBytes>47 45 54 0a 0a 0a 31 37 30........</StringToSignBytes>
        <RequestId>S3T66NPSHTKCDAQ7</RequestId>
        <HostId>7EPjXVhzo2S3fBt7fNivJjlnpzcM7Ii9lbsQG4rXYDsoI25+vYvCMS6Cfy1uvVpkHRQVBsqZZI8=</HostId>
        </Error>
    

Your assistance in resolving this issue would be greatly appreciated. Thank you!

Answer №1

x-amz-security-token:FwoGZXIvYXdzEKf//////////wEaDDy3nYkyTaxu1hEt6iLnAcXSYnhu0Oq0K7AeEc/quuBjIyqMfZON6gbHFZ3/ZLi7yDwPtdlKsiacTDSKiav1XuQI1WP+aXePJ+RwgtJesC177Jmfg=/index.html
/index.html at the end.

http-proxy is mistakenly including /index.html in the query string. It seems to treat target as the base URL for proxied requests, requiring the path to be appended.

s3.getObject and stream its results upstream.

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

Configuring headers for all responses in Express.js

While working with Express for web services, I require the responses to be encoded in utf-8. I am aware that I can manually set the charset for each response using the following code: response.setHeader('charset', 'utf-8'); However, ...

Building an NPM module specifically designed for Ionic app development requires a strategic approach

Currently, I am in the process of creating a library for Ionic 2 that needs to be installed via NPM. However, I am facing some challenges with the traditional installation method. When trying to develop a module, you can usually use the npm link command to ...

Server-side rendering or updating of React elements

One issue I am facing in my React app is that while all components can update themselves through the browser, a specific module called jenkins-api only functions when called server side. To retrieve the data and pass it into my template, I have utilized th ...

I'm facing a dilemma while attempting to integrate babel into my node.js project

Attempting to execute the following command: npm install --save-dev babel-cli babel-preset-env babel-watch Unfortunately, encountering the error below: npm ERR! code Z_BUF_ERROR npm ERR! errno -5 npm ERR! zlib: unexpected end of file Seeking ass ...

`Grunt.js watch for Browserify`

Hi there! I'm just starting to explore Grunt.js. Up until now, my process involved running: browserify ./js/app.js -o ./js/app.bundle.js each time a file was changed and saved. Now, I am aiming to streamline this by using Grunt (version 0.4.2) wat ...

What role does a promise play in rendering code asynchronous?

While we often use promises to avoid the dreaded function callback hell, a question remains: where exactly in the event loop does the promise code execute and is it truly asynchronous? Does the mere fact that the code is within a promise make it asynchron ...

Troubleshooting connection timeouts between node.js and amqp

In my project, I am utilizing RabbitMQ through the AMQP module in Node.js with 2 producers and 2 consumers. Here is the code snippet for establishing connections for the consumers: function init_consumers( ) { console.log( 'mq: consumers connect ...

Exploring the power of Node.js and Mongoose with the query aggregation

In my node.js application, I have a schema using mongoose that looks like this: var todoSchema = new Schema({ task: String, description: String, date: Date, status: String, checklist: Boolean, user: String }); I am trying to achieve the follo ...

One may wonder about the distinction between running `npm i` and `npm i <package name>`

I am currently working on a React Native project where the package.json contains a specific version of react. However, I am hesitant to run npm i for fear that it will install the latest version of react instead. I wonder if running npm i will respect th ...

The URI entered is not valid: The parsing of the hostname failed. Electron Builder

Having an issue while trying to build an electron app using squirrel, even though the iconUrl is valid. Here is my package.json configuration: "squirrelWindows": { "iconUrl": "http://95.85.39.111:5005/skylog.ico" }, Error message received: An unhand ...

The specific Local Npm module named "GRUNT-PLUGIN-MODULE" could not be located. Have you installed this module? What could be the reason for its absence?

Steps to integrate your new grunt-plugin module with your project. Here is an example of directory structure: |-- xyz-project | |-- ... | |-- app.js | |-- Gruntfile.js --> `grunt.loadNpmTasks('my-custom-grunt-plugin');` | ...

The Vercel platform encountered an error stating that '`ZLIB_1.2.9' was not found

I'm attempting to utilize canvas in a serverless function on Vercel, but I've encountered an unfamiliar error: Error: /lib64/libz.so.1: version ZLIB_1.2.9' not found (required by /var/task/api/node_modules/canvas/build/Release/libpng16.so.1 ...

Is there a way to configure json-server, when utilized as a module, to introduce delays in its responses

json-server provides a convenient way to introduce delays in responses through the command line: json-server --port 4000 --delay 1000 db.json However, when attempting to achieve the same delayed response using json-server as a module, the following code ...

Node Pagination and Filtering feature malfunctioning

I am currently working on incorporating Pagination and Filtering in the backend functionality. This controller receives input such as Page number and Filtering conditions. Controller:- const getPosts = asyncHandler(async (req, res) => { const { ...

Is there internal access to the "access property" within the "data property" in JavaScript?

I have come to understand that there are two types of properties in objects: data properties and accessor properties. It is possible to access the "data property" without using an "accessor property," as shown below: const person = { name: 'Pecan&a ...

Sinopia, the database for your local NPM registry

Sinopia caught my attention with its feature of having a local npm registry. I have some queries regarding this module: The Sinopia Documentation states that "Sinopia keeps its own small database"; but what specific database is actually being used? Addit ...

Automatically scrolling through a nested list in ReactJs

I have a chat list integrated into my web application. The entire webpage is scrollable, as shown in the image at the bottom. I would like the messages list to automatically scroll to the bottom whenever a new message arrives. To achieve this, I created a ...

Tips for utilizing the async.js library in combination with the await keyword?

Currently, I am working on integrating the async library to continuously poll an API for a transaction until it is successful. router.get('/', async function (req, res) { let apiMethod = await service.getTransactionResult(txHash).execute(); ...

Every time I attempt to run "npm install" on Visual Studio Code, I encounter an error

Every time I try to run npm install, I encounter this error. My node version is 18.9.1 and I have exhausted all possible solutions. Any help would be greatly appreciated. '''npm ERR! code ENOENT npm ERR! syscall open npm ERR! path C:\Us ...

Problems persist with storing Node.js values in database

I need help inserting values from a socket emit into my database. Here is the code I am using: socket.on("chat message", (data) => { var sql = "INSERT INTO tbl_user_chats (sender,receiver,message,created_at,ad_id,category_id) VALU ...