Search code examples
node.jsfirebaseexpressfirebase-authenticationbusboy

How to validate Firebase AuthToken before handling the rest of the request


I have a NodeJS server that accepts form-data that includes a Firebase token a phone number and a file. I'm using busboy and express to get the data from the form. The code looks like this:

    function validateAuthToken(authToken) {
        if (authToken) {
            admin.auth().verifyIdToken(authToken).then(function(decodedToken) {
            console.log("Verified auth token uid is:" + decodedToken.user_id);
                    return decodedToken;
                }).catch(function(error) {
                    console.log("Failed to verify authToken with error:" + error);
                });
            }
        }
    }


    app.post("/shout", function(req, res) {
        var busboy = new Busboy({ headers: req.headers });


        busboy.on('field', function(fieldName, value) {
            var decodedToken = null;
            var recPhone = null;
            switch (fieldName) {
                case constants.MSG_FORM_PART_AUTH_TOKEN:
                    decodedToken = validateAuthToken(value);
                    break;
                case constants.MSG_FORM_PART_RECIPIENT_PHONE:
                    //validate the phone number only if the token is valid
                    recPhone = validatePhoneNumber(decodedToken.phone_number, value);
                    break;
            }
        });

        busboy.on('file', function(fieldName, file) {
            shoutFileName = path.join(constants.SHOUT_FILES_PATH, shortid.generate());
            file.pipe(fs.createWriteStream(shoutFileName));
        });

        busboy.on('finish', function() {
            //save the file if the token is valid
        });

        return req.pipe(busboy);
    });

My problem is that I need to finish the token validation before I can validate the phone number or save the file to the server. The verifyIdToken uses a promise to validate the Firebase token and so I can't use await on it. In the meantime busboy keep parsing the rest of the request. How do I serialize the process?

Should I save all the data and begin the verification only after busboy finish event is emitted?


Solution

  • After getting no answers and chatting with a developer offline I implemented the busboy finish event.

    I first saved the file to a TMP folder. Then I validated the token and only after getting the validation result proceeded to save the file to a permanent location. The downside of this is that I cannot stop big files from being saved if the validation fails but since I limit the files to be small any way it was a better straight forward way to go.