Is anyone else using lambda authorizers to handle ...
# help
d
Is anyone else using lambda authorizers to handle their auth? Is live lambda dev working for you? After the first try, under the assumption that my authorizer is setup correctly, the lambda errors out with 500s. I’ll share more code snippets in the morning. Hoping I can recreate this.
Ah damn, it was indeed a silent error from aws. This is the comment in the @types/aws-lambda
Copy code
// Poorly documented, but API Gateway will just fail internally if
// the context type does not match this.
// Note that although non-string types will be accepted, they will be
// coerced to strings on the other side.
So for anyone that wants to use an authorizer lambda, make sure all your values are primitive types.
Hmm, the dev experience is still pretty bad here. It seems if the target lambda (the one sitting behind the authorizer lambda) throws an exception, it also takes down the authorizer lambda.
Hey @Frank! I'm unable to deduce whether the bug is in the SST implementation or if its compounded by some other factor. My team has been keen on using an authorizer lambda, but this is a blocker.
I'll try to replicate on a barebones project later.
f
Hey @Dennis Dang, here’s a working example I had that used custom authorizer to implement BASIC auth:
Copy code
// lib/ApiStack.js

import * as apigAuthorizers from "@aws-cdk/aws-apigatewayv2-authorizers";
import * as sst from "@serverless-stack/resources";

export class MainStack extends sst.Stack {
  constructor(scope: <http://sst.App|sst.App>, id: string, props?: sst.StackProps) {
    super(scope, id, props);

    const authorizer = new apigAuthorizers.HttpLambdaAuthorizer({
      authorizerName: "LambdaAuthorizer",
      //responseTypes: [apigAuthorizers.HttpLambdaResponseType.SIMPLE],
      handler: new sst.Function(this, "Authorizer", {
        handler: "src/authorizer.main",
      }),
    });

    const api = new sst.Api(this, "Api", {
      defaultAuthorizationType: sst.ApiAuthorizationType.CUSTOM,
      defaultAuthorizer: authorizer,
      routes: {
        "GET /": "src/lambda.main",
      },
    });

    this.addOutputs({
      Endpoint: api.url,
    });
  }
}
And here’s the authorizer Lambda function:
Copy code
// src/authorizer.js

export const main = async (event, context, callback) => {
  const authHeader = event.headers.Authorization;
  let username, password;

  if (authHeader) {
    const base64Info = authHeader.split(' ')[1];
    // Stored as 'username:password' in base64
    const userInfo = new Buffer(base64Info, 'base64').toString();
    [username, password] = userInfo.split(':');
  }

  return username === "hello" && password === "world"
    ? callback(null, {
      principalId: '*',
      policyDocument : {
        Version : '2012-10-17',
        Statement : [{
          Action : 'execute-api:Invoke',
          Effect : 'Allow',
          Resource : '*',
        }],
      }
    })
    : callback('Unauthorized');
};
d
thanks i'll test this out