Node.js: Google cloud storage credentials not loading in production

501 Views Asked by At

For my express server app, I have an auth.json file for my authentication which works fine in development. In my deployed app the authentication is failing when I upload a file saying the error:

Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.

Why is my authentication failing when it is deployed?

Currently all my buckets in this project are Public To Internet, and the roles allUsers and the Service Account Email both have full Storage Object Creator/Viewer/Admin roles. The auth.json file is on the same hierarchical level as the app.js.

Here is my app.js code with all libraries and the post request that uploads the image. It should be noted that the uploadThumb() function works every time, but the uploadFile is the one that causes the error shown below.

const express = require("express");
const bodyParser = require("body-parser");
const _ = require("lodash")
const ejs = require("ejs");
const sharp = require('sharp');
const multer = require("multer");
const fs = require("file-system");
const imageThumbnail = require("image-thumbnail");
const {Storage} = require('@google-cloud/storage');
const storage = new Storage({keyFileName: "auth.json"});
const app = express();

//this writes the user submitted image to the local file system
var localStorage = multer.diskStorage({
  destination: function (req, file, cb) {
    const imageDirect = req.body.categories + "/" + req.body.subcat.charAt(0).toUpperCase() + req.body.subcat.slice(1).replace(/ /g, "-") + "/";
    var dir = "./" + imageDirect;
    if(!fs.existsSync(dir)) {
      fs.mkdirSync(dir);
    }
    cb(null, imageDirect)
  },
  filename: function (req, file, cb) {
    let tempImageName = file.originalname;
    req.imageName = tempImageName
    cb(null, tempImageName.replace(/ /g, "-"))
  }
});

var upload = multer({storage: localStorage});

app.post("/upload", upload.single("image"), (req, res) => {

//These define the paths and destinations dynamically
  let cat = req.body.categories;
  let subCatLiteral = req.body.subcat.split(" ");
  let subCat = ""
  for (i=0; i < subCatLiteral.length; i++) {
    var eachWord = subCatLiteral[i].charAt(0).toUpperCase() + subCatLiteral[i].slice(1);
    if (i < subCatLiteral.length-1) {
    subCat = subCat.concat(eachWord + "-");
    } else {
    subCat = subCat.concat(eachWord);
    }
  }
  let img = req.imageName.replace(/ /g, "-");
  let imgTitle = img.split(".")[0];
  let imagePath = cat + '/' + subCat + '/' + img


 //This is uploaded 1st
  async function uploadThumb() { 
    await storage.bucket(thumbs).upload(imgTitle + "-thumb.jpg", {metadata: {cacheControl: "no-cache"}, gzip: true, destination: cat + "/" + subCat + "/" + req.body.name.replace(/ /g, "-") + "-thumb.jpg"})
      uploadFile().catch(console.error);
      fs.unlinkSync(imgTitle + "-thumb.jpg")  //deletes file after upload 
  }


//This is uploaded 2nd, causing  the error
  async function uploadFile() {   
    await storage.bucket(bucketName).upload(imagePath, {metadata: {cacheControl: "no-cache"}, resumable: true, gzip: true, destination: cat + "/" + subCat + "/" + req.body.name.replace(/ /g, "-") + ".jpg"})
      //deletes file after upload
      fs.unlinkSync(`${cat}/${subCat}/${img}`)
      fs.rmdirSync(`./${cat}/${subCat}/`)
      setTimeout(() => {
        fs.rmdirSync(`./${cat}`)
      }, 500)
    await listFiles().catch(console.error);
  }


 //This function starts the chain of uploads
 sharp(imagePath) 
     .resize(null, 300).toFile(imgTitle + "-thumb.jpg", function(err) {
       if (!err) console.log("image resized");
       uploadThumb().catch(console.error);
   })

  res.redirect("/upload#upload");
});

If anybody knows why this fails in production, or where exactly in the docs I can find the solution I would appreciate it.

Here is the most recent error reporting to the passenger.log

App 21701 output: Error: Could not load the default credentials. Browse to https://cloud.google.com/docs/authentication/getting-started for more information.
App 21701 output:     at GoogleAuth.getApplicationDefaultAsync (/home/kaylakos/nodevenv/rootdir/kayla/12/lib/node_modules/google-auth-library/build/src/auth/googleauth.js:157:19)
App 21701 output:     at processTicksAndRejections (internal/process/task_queues.js:97:5)
App 21701 output:     at async GoogleAuth.getClient (/home/kaylakos/nodevenv/rootdir/kayla/12/lib/node_modules/google-auth-library/build/src/auth/googleauth.js:490:17)
App 21701 output:     at async GoogleAuth.request (/home/kaylakos/nodevenv/rootdir/kayla/12/lib/node_modules/google-auth-library/build/src/auth/googleauth.js:543:24)
App 21701 output:     at async Upload.makeRequest (/home/kaylakos/nodevenv/rootdir/kayla/12/lib/node_modules/gcs-resumable-upload/build/src/index.js:320:21)
App 21701 output:     at async Upload.createURIAsync (/home/kaylakos/nodevenv/rootdir/kayla/12/lib/node_modules/gcs-resumable-upload/build/src/index.js:145:22)
0

There are 0 best solutions below