1

I am making an app which includes a messaging feature. Through the messaging feature, users can send photos to others users. These photos should be completely private.

At first, I thought of S3's signedURL feature. But then I realized that I cannot make caching work which is done by my CDN provider and my client side because caching is done based on URLs.

So I moved on to CloudFront's signed cookie. It seemed promising at first, but I found another problem. Users who got signed cookies can access to any content in the allowed scope. But I should not allow to show photos that were sent in other chat rooms. Users who have signed cookies should not be able to access to photo urls that were not shared in their rooms. So I cannot use signed cookies.

I moved on to CloudFlare and found a post that they were allowed to use special cache keys instead of url based caching. (https://blog.bigbinary.com/2019/01/29/how-to-cache-all-files-using-cloudflare-worker-along-with-hmac-authentication.html) I do not know how much the Enterprise Plan is, but Business Plan which is one level below is $200/month.

The business plan allows CloudFlare users to use token authentication. (https://blog.cloudflare.com/token-authentication-for-cached-private-content-and-apis/) (https://support.cloudflare.com/hc/en-us/articles/115001376488-How-to-setup-Token-Authentication-) I might be able to utilize this token authentication by making my images including tokens like this:

<Image source={{
          uri: 'https:image_url.jpeg',
          method: 'GET',
          headers: {
            Authorization: token
          },
     }}
     style={{width: width, height: height}}
/>

Another thing I could do is getting signed URLs from CloudFront, not from a S3 level. In that way, I can make my CDN(CloudFront, in this case) to properly cache my S3 images and then make unique URLs per photo. But I still have to deal with client side caching as URLs clients see are always different. I have to save URLs in Localstorage as this(https://stackoverflow.com/a/37817503) answer suggested. Or I can use a React Native caching library. However, I will deploy this app on the web as well as mobile environment, so I am not sure if it will be a viable option for me to use such caching libraries.

To sum up, signed URLs cause two-level problems. It does not work with CDN caching. It does not work with client caching. I should use CloudFront's signed URLs and deal with client side caching(which is not ideal) Or I should use CloudFlare's token method. Bandwidth is free for CloudFlare, though Business Plan costs $200. So will it be worth it if I assume my app scales well?

What discourages me from using CloudFlare is it is not well documented. I have to deal with workers in CloudFlare, but the only document I found about how to use signed URL in the CDN level is this (https://developers.cloudflare.com/workers/about/tips/signing-requests/#verifying-signed-requests) And the only one I found about how to access to S3 private bucket from CloudFlare is this (https://help.backblaze.com/hc/en-us/articles/360010017893-How-to-allow-Cloudflare-to-fetch-content-from-a-Backblaze-B2-private-bucket)

Is CloudFlare with token verification method the right way to go for me? Is there any other method I can try out?

Grateful
  • 383
  • 5
  • 18
  • What about [CloudFront signed URLs](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls.html)? – kichik Oct 06 '19 at 20:43
  • Have you tried building a custom browser Cache like [here](https://stackoverflow.com/a/76805423/824979) – piercus Aug 01 '23 at 06:59

0 Answers0