0

I have an Express server running on Lambda. There is a custom lambda authorizer attached to his lambda which passes auth headers via events.

My goal is to extract these request context values and attach them to the event headers of the lambda and then pass it on to the Express request headers which can then be used across my route implementations

lambda.ts

'use strict';

import { APIGatewayProxyHandler } from "aws-lambda";
import serverlessExpress from "@vendia/serverless-express";
import app from "./express.app";
import MongoDbConnectionService from "./services/mongodb-connection-service";

let connection = null;
let serverlessExpressInstance = null;

export const handler: APIGatewayProxyHandler = async (event, context, callback) => {
  context.callbackWaitsForEmptyEventLoop = false;

  const authHeaders = (event.requestContext || {}).authorizer || {};
  
  if(connection == null) {
    connection = await MongoDbConnectionService.connect();
  }

  if(serverlessExpressInstance) {
    return serverlessExpressInstance(event, context, callback);
  }
  
  ['principalId'].forEach((headerKey) => {
    if (authHeaders.hasOwnProperty(headerKey)) {
      event.headers[headerKey.toLowerCase()] = authHeaders[headerKey];
    }
  });

  console.log("Event headers: ", event.headers);
  
  serverlessExpressInstance = serverlessExpress({ app });
  return serverlessExpressInstance(event, context, callback);
};

As you can see that I am extracting "principalId" from the event.requestContext and adding it to the event.headers. When I log the event.headers it does show that "principalid" is included in it.

express server

'use strict';

import cors from 'cors';
import express from 'express';
import 'reflect-metadata';
import { ExpressRouter } from './routes/routes';
import path from 'path';

class ExpressApplication {
  public app: express.Express;
  private readonly router: express.Router;

  constructor() {
    const expressRouter = new ExpressRouter();
    this.app = express();
    this.router = express.Router();
    this.app.use(cors());
    this.app.use(express.json());
    this.app.use(express.urlencoded({ extended: true }));
    expressRouter.setRoutes(this.app, this.router);
  }
}

const app = new ExpressApplication();

export default app.app;

route

app.post("/calendar-integration", requestValidator(CalIntegrationValidationModel), (req: Request, res: Response) => {
  console.log(req.headers);
  res.send("Testing this shit");
});

In the above console.log(req.headers) the principalid header is missing. I am unable to figure out what I might be doing wrong, this has been working for me when I was using aws-serverless-express before it got depreciated in favor of @vendia/serverless-express.

codeinprogress
  • 3,193
  • 7
  • 43
  • 69

1 Answers1

0

Seems like we need to pass the custom headers to event headers via multiValueHeaders.

So the code should be

['principalId'].forEach((headerKey) => {
    if (authHeaders.hasOwnProperty(headerKey)) {
      event.multiValueHeaders[headerKey.toLowerCase()] = authHeaders[headerKey];
    }
  });
codeinprogress
  • 3,193
  • 7
  • 43
  • 69