R2: Create a presigned URL with Temporary access credentials

Hi! I'd like to know what's the proper way to create a presigned URL for an object with temporary access credentials. Is that even possible?

This is my try with typescript:
export function generatePresignedURL(object: string, bucket: string, region: string, accessKeyId: string, secretAccessKey: string, sessionToken: string = ''): string {
  const amzDate = new Date().toISOString().replace(/[:-]/g, '').replace(/\.\d{3}/, '');
  const dateStamp = amzDate.slice(0, 8);
  const algorithm: string = "AWS4-HMAC-SHA256";
  const credentialScope: string = `${dateStamp}/${region}/s3/aws4_request`; // %2F is /
  const expires = 3600; // 1 hour
  const url: URL = new URL(`https://${import.meta.env.VITE_APP_R2_ACCOUNT_ID}.eu.r2.cloudflarestorage.com/${bucket}/${object}?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=${accessKeyId}%2F${encodeURIComponent(credentialScope)}&X-Amz-Date=${amzDate}&X-Amz-Expires=${expires}&X-Amz-SignedHeaders=host`);
  if(sessionToken != '') {
    url.searchParams.append('X-Amz-Security-Token', encodeURIComponent(sessionToken));
  }
  const host = url.hostname;
  const canonicalUri = new URL(url).pathname;
  const canonicalQueryString = new URL(url).searchParams.toString();
  var signedHeaders = 'host';
  var canonicalHeaders = `host:${host}\n`;
  if(sessionToken != '') {
    signedHeaders += ';x-amz-security-token';
    canonicalHeaders += `x-amz-security-token:${encodeURIComponent(sessionToken)}\n`;
  }
  const canonicalRequest = `GET\n${canonicalUri}\n${canonicalQueryString}\n${canonicalHeaders}\n${signedHeaders}\nUNSIGNED-PAYLOAD`
  const stringToSign = `AWS4-HMAC-SHA256\n${amzDate}\n${credentialScope}\n${CryptoJS.SHA256(canonicalRequest).toString()}`;
  const signingKey = getSignatureKey(secretAccessKey, dateStamp, region, 's3');
  const signature = CryptoJS.HmacSHA256(stringToSign, signingKey).toString();
  const presignedUrl = url.toString() + `&X-Amz-Signature=${signature}`;

  return presignedUrl;
}
Was this page helpful?