Skip to content

Instantly share code, notes, and snippets.

@TanguyDucky
Created November 12, 2019 17:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TanguyDucky/6fde83a2a3e91802a6ec4768a40b23aa to your computer and use it in GitHub Desktop.
Save TanguyDucky/6fde83a2a3e91802a6ec4768a40b23aa to your computer and use it in GitHub Desktop.
Host a static website with Google Cloud Storage using Firebase Cloud Function as a proxy to secure the access with HTTP basic authentication
/**
* Declare a single cloud function "componentsProxy"
*/
const functions = require("firebase-functions");
const { server } = require("./server");
const componentsProxy = functions.https.onRequest(server);
module.exports = {
componentsProxy
};
{
"name": "functions",
"description": "Cloud Functions for Firebase",
"scripts": {
"serve": "firebase serve --only functions",
"shell": "firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "8"
},
"dependencies": {
"@google-cloud/storage": "^4.1.1",
"express": "^4.14.1",
"express-basic-auth": "^1.2.0",
"firebase-admin": "^8.6.0",
"firebase-functions": "^3.3.0",
"fs-extra": "^8.1.0",
"google-auth-library": "^5.5.1"
},
"devDependencies": {
"firebase-functions-test": "^0.1.6"
},
"private": true
}
/**
* 1st middleware
* Check for HTTP basic Auth
* If not OK, ask the browser for it.
* If OK, proceed to next middleware
*
* 2nd middleware
* Use google-cloud-storage client to download locally a version of the requested file
* Then stream this file as a response
*/
const express = require("express");
const basicAuth = require("express-basic-auth");
// Imports the Google Cloud client library
const { Storage } = require("@google-cloud/storage");
// Creates a client from a Google service account key; A service is allowed to access the GCS bucket hosting the files
const storage = new Storage({ keyFilename: "./my_service_key.json" });
const fs = require("fs-extra");
const server = express();
// Basic HTTP authentication
server.use(
basicAuth({
users: { username: "Hey this is a strong password or ??? yeah maybe not :-/" },
challenge: true // trigger most browsers to ask for credentials
})
);
// Catch all requests
server.use("/**", async (req, res) => {
const bucketName = "MY_GCS_BUCKET_NAME";
const srcFilename = req.params[0] || "index.html";
const destFilename = "/tmp/" + srcFilename;
console.log("file to fetch", srcFilename);
const options = {
destination: destFilename
};
// Create local path to file if not exist
fs.outputFileSync(destFilename, "");
// Downloads the file locally
await storage
.bucket(bucketName)
.file(srcFilename)
.download(options);
console.log(
`gs://${bucketName}/${srcFilename} downloaded to ${destFilename}.`
);
// Stream the file asa response
fs.createReadStream(destFilename).pipe(res);
});
module.exports = {
server
};
@TanguyDucky
Copy link
Author

Those files live under a functions folder in my firebase project

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment