0

I am trying to fetch a jpg image from AWS S3 Bucket using a HTTP GET request in React-Native.

So far I was following these 2 documentations from Amazon :

Here is the logic I implemented so far. When my component render, I am doing the following :

import { Auth } from 'aws-amplify';
import Moment from 'moment';
import sha256 from 'crypto-js/sha256';
var CryptoJS = require("crypto-js");


...

Auth.currentCredentials()
    .then(async credentials => {
        let awsHost = 'https://myAwsHost.amazonaws.com'
        let awsPath = '/public/pathToMyImage.jpg'
        let accessKeyId = credentials.accessKeyId
        let secretAccessKey = credentials.secretAccessKey
        let sessionToken = credentials.sessionToken
        let awsDate = Moment().utc().format("YYYYMMDD")
        let awsRequestDateTime = Moment().utc().format("YYYYMMDD" + "T" + "HHmmss") + "Z"
        let awsRegion = "myRegion"
        let awsService = "s3"
        let awsRequest = "aws4_request"
        let awsAlgorithm = "AWS4-HMAC-SHA256"
        let awsCredentialScope = awsDate + "/" + awsRegion + "/" + awsService + "/" + awsRequest
        let awsHTTPRequestMethod = "GET"
        let awsSignedHeaders = "host;x-amz-content-sha256;x-amz-date;x-amz-security-token"
        let awsCanonicalURI = awsHost + awsPath
        let awsCanonicalQueryString = ""

        // Step 1 
        let canonicalRequest =
            awsHTTPRequestMethod + '\n' +
            awsCanonicalURI + '\n' +
            awsCanonicalQueryString + '\n' +
            "X-Amz-Content-Sha256".toLowerCase() + ":" + sha256("") + "\n" +
            "X-Amz-Date".toLowerCase() + ":" + awsRequestDateTime.trim() + "\n" +
            "X-Amz-Security-Token".toLowerCase() + ":" + sessionToken + "\n" +
            awsSignedHeaders + '\n' +
            sha256("")

        // Step 2 : 
        let stringToSign =
            awsAlgorithm + "\n" +
            awsRequestDateTime + "\n" +
            awsCredentialScope + "\n" +
            sha256(canonicalRequest)

        // Step 3 : 
        let kSecret = secretAccessKey
        let kDate = CryptoJS.HmacSHA256("AWS4" + kSecret, awsDate)
        let kRegion = CryptoJS.HmacSHA256(kDate, awsRegion)
        let kService = CryptoJS.HmacSHA256(kRegion, awsService)
        let kSigning = CryptoJS.HmacSHA256(kService, awsRequest).toString(CryptoJS.enc.Hex)

        let awsSignature = CryptoJS.HmacSHA256(awsDerivedSignInKey, stringToSign).toString(CryptoJS.enc.Hex)

        let awsAuthorization = awsAlgorithm + " Credential=" + accessKeyId + "/" + awsCredentialScope + ", SignedHeaders=" + awsSignedHeaders + ", Signature=" + awsSignature

        // Fetching the image with an HTTP GET request to AWS S3 Buckets
        try {
            await fetch(
                awsCanonicalURI,
                {
                    headers: {
                        'X-Amz-Security-Token': sessionToken,
                        'X-Amz-Content-Sha256': sha256("").toString(),
                        'X-Amz-Date': awsRequestDateTime,
                        'Authorization': awsAuthorization
                    },
                }
             ).then(res => {
                 console.log("HTML status : " + res.status) // Status return : Error 403
             });
         } catch (error) {
             console.error(error);
         }
     })
}

When I am trying to execute the same GET request with postman it work's and it retrieve the image from AWS S3 Buckets. The only difference between my request and the one generated by postman is the Signature.

I know that I can fetch images from S3Image component from aws-amplify-react-native but it is not what I am trying to achieve.

Main goal

Finally, I am looking to execute those HTTP GET Request's in order to use them in FastImage from the module react-native-fast-image and use it in order to cache easely images in my react-native application.

If anyone has an answer to my problem or a better alternative to what I am trying to achieve, be my guest!!

Citrix
  • 257
  • 4
  • 14

1 Answers1

0

If it works in postman, You can get the Axios code sample for that using postman. Checkout the gif below.

enter image description here

vijay krishna
  • 514
  • 4
  • 14