Search code examples
node.jshmaccloudflare-workers

Cloudflare worker - verify presigned url


I am playing around with presigned urls. Server generates a presigned url using node, works great with object storage. Now I am trying to verify the presigned url with a Cloudflare worker, but I don't get it.

Any solutions on the worker side for this server code?

function expireDate() {
    const d = new Date();
    d.setUTCHours(5, 0, 0, 0); // 5 am
    d.setUTCDate(d.getDate() + 2); // + 2 days
    return Math.floor(d.getTime() / 1000);
}

function generateSignedUrl(url) {
    const expire_date = expireDate();

    // Create HMAC
    const hmac = crypto.createHmac('sha256', 'mystrongkey');
    // Pass the data to be hashed
    console.log(util.format('%s\n%d\n%s', 'GET', expire_date, url));
    data = hmac.update(util.format('%s\n%d\n%s', 'GET', expire_date, url));
    // Create HMAC in the required format
    tempUrlSig = data.digest('hex');

    return url + '?temp_url_sig=' + tempUrlSig + '&temp_url_expires=' + expire_date;
}

const presigned_url = generateSignedUrl('https://example/test.jpg')

I also played around with Cloudflares example https://developers.cloudflare.com/workers/examples/signing-requests - but I am not able to fix TypeError: Cannot read property 'subtle' of undefined (yeah, I tried const { subtle } = require('crypto').webcrypto; and so on - no idea!)

I am also happy with a new server code, it just have to work :-) Also searched for a way to verify the AWS SDK S3 getSignedUrl output with Cloudflare (or even Node...), but didn't found a solution.

Finally I just want to secure a private bucket with Cloudflare in the middle (bandwidth alliance).


Solution

  • The JavaScript runtime of Cloudflare Workers is not based on Node. So there won't be a pre-bundled module called crypto that you can require or import.

    If you start from these template projects with Webpack configured, required/imported modules are typically those which you have installed manually (e.g. via npm install/yarn add foobar and later being listed as dependencies in package.json). In other words, it is somewhat alike to writing front-end JS.

    The Workers provides a built-in WebCrypto-compliant cryptography library implementation as documented here: https://developers.cloudflare.com/workers/runtime-apis/web-crypto. According to the doc, crypto is just a global object that can be accessed directly with importing.

    Even though I do not have a try, I suppose the link to the example you given is a completed Worker script with no more modifications needed to test. That is, just copy&paste into the online editor of Workers and test.