SignatureDoesNotMatch: SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided

59 Views Asked by At

I'm using recordRTC react package to record the screen and then every 1 minute, I'm trying to upload the blob returned by recordRTC to S3 using multi-part uploads. I'm using AWS SDK v3. I'm able to execute createMultipartUpload and get the UploadId, abort multi-part command using AbortMultipartUploadCommand, but when I execute UploadPartCommand, it throws the following error:

default-error-handler.js:5 Uncaught (in promise) SignatureDoesNotMatch: The request signature we calculated does not match the signature you provided. Check your key and signing method.
    at throwDefaultError (http://localhost:3000/static/js/bundle.js:30691:20)
    at http://localhost:3000/static/js/bundle.js:30704:5
    at de_UploadPartCommandError (http://localhost:3000/static/js/bundle.js:19856:10)
    at async http://localhost:3000/static/js/bundle.js:28426:20
    at async http://localhost:3000/static/js/bundle.js:24100:18
    at async http://localhost:3000/static/js/bundle.js:28311:13
    at async http://localhost:3000/static/js/bundle.js:38590:18
    at async http://localhost:3000/static/js/bundle.js:40650:20
    at async http://localhost:3000/static/js/bundle.js:40688:14
    at async http://localhost:3000/static/js/bundle.js:23830:22

I've tried everything, but non of the solutions available are working.

This is the relevant piece of code for reference:

export const getS3Client = () => {
  return new S3Client({
    region: process.env.REACT_APP_AWS_REGION,
    credentials: fromCognitoIdentityPool({
       client: new CognitoIdentityClient({ region: ML_SERVICES_REGION }),
       identityPoolId: IDENTITY_POOL_ID,
    }),
    sslEnabled: false,
    signatureVersion: 'v4',
    logger: {
      info: console.info,
      warn: console.warn,
      error: console.error,
    }
  });
};
  const [isScreenRecording, setIsScreenRecording] = useState(false);
  const [uploadInProgress, setUploadInProgress] = useState(false);
  const chunks = useRef([]);
  const S3Client = useRef(null);
  const multipartUploadId = useRef(null);
  const nextPartNumber = useRef(1);
  const recorderRef = useRef(null);
  const streamRef = useRef(null);

  const uploadToS3 = async () => {
    if (chunks.current.length === 0) {
      setUploadInProgress(false);
      return;
    }

    setUploadInProgress(true);
    const chunk = chunks.current[0];
    console.log(chunk);

    if (!multipartUploadId.current) {
      S3Client.current = getS3Client();
      const { UploadId } = await S3Client.current.send(
        new CreateMultipartUploadCommand({
          Bucket: S3_BUCKET,
          Key: 'screen-recording/recording.webm',
          ContentType: "video/webm;codecs=vp8",
        })
      );
      multipartUploadId.current = UploadId;
      console.log("UploadId: ", UploadId)
    }

    const command = new UploadPartCommand({
      Bucket: S3_BUCKET,
      Key: 'screen-recording/recording.webm',
      PartNumber: String(chunk.partNumber),
      Body: chunk.blob,
      UploadId: multipartUploadId.current
    });

    const response = await S3Client.current.send(command);
    console.log(response);
    chunks.current.shift();
    uploadToS3();
  };

  const startScreenRecording = async () => {
    const hasScreenAccess = await getScreenAccess();
    if (!hasScreenAccess) {
      console.log("Couldn't get access to the screen.");
      cleanup();
      return;
    }

    recorderRef.current = RecordRTC(streamRef.current, {
      type: 'video',
      timeSlice: 60 * 1000, // 1 minute in milliseconds
      ondataavailable: (blob) => {
        chunks.current.push({
          blob,
          partNumber: nextPartNumber.current,
        });

        console.log(nextPartNumber.current);
        nextPartNumber.current += 1;
        if (chunks.current.length === 1) {
          uploadToS3();
        }
      },
    });

    setIsScreenRecording(true);
    recorderRef.current.startRecording();
  };

Note: I'm also using AWS Transcribe and Polly somewhere else in the codebase and they're running in a different region, so I've two regions. I've also tried this without Cognito, by replacing credentials with this, but still same issue:

    credentials: {
      accessKeyId: process.env.REACT_APP_AWS_ACCESS_KEY_ID,
      secretAccessKey: process.env.REACT_APP_AWS_SECRET_ACCESS_KEY,
    },

I'm completely blocked now. Any help is much appreciated. Thanks in advance.

0

There are 0 best solutions below