Skip to content

Instantly share code, notes, and snippets.

@apotox
Last active June 6, 2021 08:09
Show Gist options
  • Save apotox/a192bcd9cf636c135e7664a7da8a39e5 to your computer and use it in GitHub Desktop.
Save apotox/a192bcd9cf636c135e7664a7da8a39e5 to your computer and use it in GitHub Desktop.
AWS custom api gateway authorizer using firebase auth JWT
const admin = require('firebase-admin');
//from your firebase project service
const serviceAccount = {
"type": "",
"project_id": "",
"private_key_id": "",
"private_key": "",
"client_email": "",
"client_id": "",
"auth_uri": "",
"token_uri": "",
"auth_provider_x509_cert_url": ",
"client_x509_cert_url": ""
}
//or require('./serviceAccountKey.json');
const initializeSdk = function () {
// Check if Firebase Admin SDK is already initialized, if not, then do it
if (admin.apps.length == 0) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: process.env.FIREBASE_DATABASE_URL // <----- LOOK !!
});
}
}
// Helper funtion for generating the response API Gateway requires to handle the token verification
const generateIamPolicy = (effect, resource, data) => {
const authResponse = {};
// Define a user object that passes user data and other user informationd decoded from the Firebase token to the Lambda API handler
const user = {};
// Populate the API Gateway user principalId with the Firebase user id, or 'unavailable' if not returned from Firebase
data ? authResponse.principalId = data.user_id : 'unavailable';
// Map values into context object passed into Lambda function, if data is present
if (data) {
user.email = data.email;
user.email_verified = data.email_verified;
user.uid = data.uid; // firebase unique id
authResponse.context = user;
}
if (effect && resource) {
var policyDocument = {};
policyDocument.Version = '2012-10-17';
policyDocument.Statement = [];
var statementOne = {};
statementOne.Action = 'execute-api:Invoke';
statementOne.Effect = effect;
statementOne.Resource = resource;
policyDocument.Statement[0] = statementOne;
authResponse.policyDocument = policyDocument;
}
return authResponse;
}
module.exports.firebase = function(event, context){
if (!event.authorizationToken) {
context.fail('Unauthorized'); // 401 status code
return;
}
// If auhorizationToken is present, split on space looking for format 'Bearer <token value>'
const tokenParts = event.authorizationToken.split(' ');
const tokenValue = tokenParts[1];
// Return from function if authorization header is not formatted properly
if (!(tokenParts[0].toLowerCase() === 'bearer' && tokenValue)) {
context.fail('Unauthorized');
return;
}
initializeSdk();
admin.auth().verifyIdToken(tokenValue)
.then(resp=>{
//replace '*' by event.methodArn if you want grant access to only the requested Lambda func <-- LOOK!!
context.succeed(generateIamPolicy('Allow', '*' , resp));
})
.catch(err=>{
console.log("firebase verification error",err)
context.succeed(generateIamPolicy('Deny', event.methodArn, null));
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment