Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

353
Views
Access Firebase Cloud Storage server-side with security rules applied

On my Firebase app, I'd like to know the recommended way to make a server-side request to Cloud Storage for Firebase on behalf of a signed-in user (authenticated via ID token), with security rules applied to the request (i.e. not with the Admin SDK).

The overall app flow currently looks like this:

  • User signs in on the client and makes a request to a Google Cloud API gateway, sending their ID token in the request header
  • API gateway authenticates user and forwards request to different endpoints in the backend API:
    • If it's a request for Firebase Authentication, the API uses Auth Admin SDK to handle it directly
    • If it's for Firestore, the API uses the x-forwarded-authorization request header (which contains the ID token originally provided by the client) forwarded by API gateway to then make a request to Firestore's REST API, so that the request can be evaluated by security rules.

For Cloud Storage, I'd like to do something similar to the Firestore case above, but there isn't a Firebase-specific REST API available in the docs. It's possible to just let the client make requests directly to Firebase (as suggested in this answer), but would prefer to keep the logic in the backend.

Are there alternatives to doing this for Storage? Please feel free to also point out if there are better ways of handling the Firebase Auth and Firestore cases mentioned above. Thanks!

EDIT: Adding more possible solutions as I find them

  • Doug's answer here and Frank's answer here suggest using the Cloud Storage REST API, where the app generates an OAuth token for the user and makes the request
  • This answer here mentions it's possible to pass an auth=IDTOKEN query parameter to the Firebase REST API:

Once you have an ID token, you can pass that to the REST API via the auth query parameter to authenticate a request. The request respects Firebase Security Rules as if the end user logged into the client was making the request.

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

There is no way to enforce Firebase's security rules for Cloud Storage when using the Admin SDK. Firebase doesn't provide a documented REST API for Cloud Storage, and I doubt the Google Cloud REST API for Storage accepts Firebase ID tokens.

So I don't really think you have good options to do this from the server on behalf of your users. The two options I can think of:

  1. Pass the necessary information back to the client, and let that access the data through the Firebase SDK - in which case the security rules are enforced.
  2. Replicate the necessary security logic in your Cloud Functions code.
over 4 years ago · Santiago Trujillo Report

0

Edit 6 Jan 2020: This method has had a couple of days testing under heavy-load. See bottom for some minor new requirements.

Original response: This isn't an answer, so much as an in-ecosystem workaround (that works for me!)

Basically, I have a similar-ish use-case with regards an offline-first/potentially insecure iot device that needs auth based storage access with security rules. This morning I took a peek at the Firebase js sdk repo and noted that a native XHR API is the main piece missing from a working node implementation.

I detailed my workaround on this github issue ... included here for convenience:

.. patching the storage library with an XHR polyfill actually appears to work (Node 15 / minimal testing so far). Specifically I've installed xmlhttprequest-ssl and imported it at the top of the storage module (in my case line 5 in @firebase/storage/dist/index.cjs.js):

var XMLHttpRequest = require("xmlhttprequest-ssl").XMLHttpRequest;

Back in the app I import firebase/storage as normal, then just load files from the local file system and upload as per the standard Firebase API:

import { firebase } from "@firebase/app";
import "@firebase/storage";

/* include Firebase setup, etc. */

const filename = 'offline-user-generated-image.jpg';
const file = fs.readFileSync(filename); // for brevity only
const ref = firebase.storage().ref().child(`test/${filename}`);

// use the buffer's underlying arraybuffer 
ref.put(file.buffer, {
  contentType: 'image/jpg', // defaults to 'application/octet-stream'
  customMetadata: {
    uid: 'abc123', // for enhanced security rules
  },
})
.then(() => console.log('done'))
.catch(e => console.log(e));

Storage rules apply to uploads (woop!) and security tokens and custom metadata are applied as expected. Also tested with `putString'. This solves some fairly drastic workarounds for my use case, as it means I can keep my logic/auth/etc. entirely within the Firebase ecosystem. Keen to hear others thoughts.

Note: I'm using patch-package to ensure the patch stays intact across installs / upgrades.

Update 6 Jan 2020: Some extra bits and pieces

It turns out that there is an uncleared timeout in the storage package that causes hell with node processes (and is likely a resource hog in all environments) .. I've submitted a PR (pretty much a clearTimeout) that resolves the issue, but in the meantime this will also need to be manually patched unless you can safely process.exit(0) in your code.

over 4 years ago · Santiago Trujillo Report

0

After considering the various options above (thanks Frank and som!), the best choice in my situation was to change things up and make Storage requests directly from the client. The 2 main reasons were:

  • It is the simplest to implement since there is already an SDK that allows you to do this
  • Interacting with Firebase Storage may involve large objects, and so user experience might suffer if there are too many network trips

When making the request from the client, som's answer above and this answer may come in useful if there's a XMLHttpRequest is not defined error

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!