Uploading to Backblaze B2 - request for input

Greetings!

This past week I’ve been attempting to add support for uploading to Backblaze B2 (https://github.com/Klowner/uppy/tree/backblaze-b2), but due to the way their API works in combination with my relative inexperience with Uppy, I’ve arrived at the point where I feel like I should reach out for community input (assuming this is even a desirable addition to Uppy).

I’ve successfully managed to upload a multipart file directly from the browser to B2 via Uppy, but due to the way Backblaze’s API works, there appears to be no way for for an authoritative server (such as Companion) to granularly authorize uploads to a particular file path within a bucket.

B2 enforces access restrictions at the application key level, as well as CORS rules on buckets. To upload a file, an API call to B2 with the application key is performed (b2_authorize_account), which returns an authorization token. The authorization token can then be handed off to the client where they can initiate uploads. All of this seems fine, except from what I can tell, there’s no way to restrict that authorization token from being used repeatedly, so a malicious user could just upload a ton of random junk to your bucket.

So, I’ve arrived at a few options:

A) Companion creates an application key for each user session (B2 has a total limit of 100 billion app key creations per account) with file prefix restrictions so uploads can only go to a certain directory within a bucket.

B) Create a write-only application key which Companion passes to B2 for authorization, and then pass that authorization token to the Uppy client for uploading. Each B2 file upload creates a unique file identifier, so the client could then tell “I just uploaded fileId” to Companion, then Companion could use a less restrictive application key to copy the file to a proper location within the bucket.

C) Uppy sends all file data directly to Companion and then you never have to worry about sharing sensitive auth tokens, but I feel like this kinda defeats the entire purpose. (Unless this is exactly the purpose of what companion is for? The docs aren’t super clear regarding the routes that the data takes)

None of these seem perfect, but I’m leaning towards B.

Thanks for reading! Any input is greatly appreciated!

-Mark

Hello there! I know this is an older post, but I’d still like to give my two cents.

I think that route B is probably the best solution. It definitely makes the most sense in this situation.

I don’t really have too much more to say on this

Good luck!
- Andrew

I’m in a similar situation. uppy user looking to save files to my Backblaze account. I’ve had some snags setting it up but I thought I’d share here since this seems to be the only uppy thread mentioning Backblaze. (Sorry-not-sorry for the necropost.)

Uppy has S3 support AWS S3 — Uppy and Backblaze has an S3 compatible API. Using this method, no custom code was necessary.

Here’s the summary what I did to set it up.

Uppy Companion is needed, along with settings for the following env variables.

COMPANION_AWS_ENDPOINT, COMPANION_AWS_BUCKET, COMPANION_AWS_KEY, COMPANION_AWS_SECRET.

On the js client side,

// full config redacted for brevity
import AwsS3Multipart from '@uppy/aws-s3-multipart';`
uppy.use(AwsS3Multipart, {
  limit: 4,
  companionUrl: '[redacted]',
})

I created a public Backblaze bucket. I’m not sure if the public setting is necessary, but I did run into an error when trying a private bucket and setting to public got me around the problem.

When I tried to upload using my uppy dashboard, I got an error regarding CORS.

Access to XMLHttpRequest at '[REDACTED FOR BREVITY]' from origin '[REDACTED FOR BREVITY]' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I think this was because Backblaze was not configured to allow s3_put from my website’s origin.

The fix for that was to set CORS via b2 command line interface. There are CORS settings in the Backblaze webUI, but it’s not enough to set it there. There is no way to set the allowedOperations, etc. in the web UI. Partial credit goes to https://www.reddit.com/r/backblaze/comments/m1fqni/comment/gqjjedq/?utm_source=share&utm_medium=web2x&context=3 for this solution.

b2-linux update-bucket --corsRules '[
    {
        "corsRuleName": "downloadFromAnyOriginWithUpload",
        "allowedOrigins": [
            "[MY_ORIGIN]"
        ],
        "allowedHeaders": [
            "*"
        ],
        "allowedOperations": [
            "s3_head",
            "s3_get",
            "s3_put"
        ],
        "exposeHeaders": [
            "ETag"
        ],
        "maxAgeSeconds": 3600
    }
]' [MY_BUCKET_NAME] allPublic

I think the above command needs to be run with a B2 App key that has the bypassGovernance capability, which for me was not the same app key used by my Uppy companion.