awslabs / cognito-at-edge

Serverless authentication solution to protect your website or Amplify application
Apache License 2.0
168 stars 54 forks source link

Sample CDK and CloudFormation templates #4

Open jeandek opened 3 years ago

jeandek commented 3 years ago

What would you like to be added:

Sample CDK and CloudFormation templates to show how to integrate the AWS services together with the package.

Why is this needed:

The desired architecture may be intimidating to users who have not done it before.

ShivamJoker commented 1 year ago

If anyone has created a template please share.

unitypark commented 1 year ago

Hi, I am working on it. I guess, I could share my application (with cdk) on this Sunday as reference of how to integrate it. 😊

unitypark commented 1 year ago

@ShivamJoker please refer my post to get overview and link to full demo app using this library. ☺️

https://www.linkedin.com/posts/junghwa-park-279129235_aws-serverless-cloudfront-activity-7053552776492060672-qUvX?utm_source=share&utm_medium=member_ios

If it's okay, I would love to contribute to share my demo app as an example of how-to section. πŸ˜ƒ

piotrekwitkowski commented 10 months ago

This is my implementation:

import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm";
import { CloudFrontRequestHandler } from "aws-lambda";
import { Authenticator } from "cognito-at-edge";
​
// Retrieve the parameter configuration and create an Authenticator instance.
// The authenticator instance will be cached between invocations.
const ssm = new SSMClient({ region: process.env.CONFIG_PARAMETER_REGION });
const authenticatorPromise = ssm
  .send(new GetParameterCommand({ Name: process.env.CONFIG_PARAMETER_NAME }))
  .then(config => new Authenticator({ ...JSON.parse(config.Parameter!.Value!), logLevel: 'trace' }));
​
export const handler: CloudFrontRequestHandler = async event => {
  try {
    const authenticator = await authenticatorPromise;
    const response = await authenticator.handle(event);
    return response;
  } catch (error) {
    console.error(error);
    return { body: '401 Unauthorised', status: '401' };
  }
};
On the CDK side, the function can be used like this (click to expand)
Imports: ```ts import { PolicyStatement } from "aws-cdk-lib/aws-iam"; import { NodejsFunction } from "aws-cdk-lib/aws-lambda-nodejs"; ``` In the Stack: ```ts const parameterStoreRegion = "us-east-1"; const viewerRequestLambda = new NodejsFunction(this, "authorizer", { entry: "lambdas/cognito-authorizer.ts", bundling: { define: { "process.env.CONFIG_PARAMETER_REGION": JSON.stringify(parameterStoreRegion), "process.env.CONFIG_PARAMETER_NAME": JSON.stringify("COGNITO_CONFIG"), }, minify: true, }, awsSdkConnectionReuse: false, }); viewerRequestLambda.addToRolePolicy( new PolicyStatement({ actions: ["ssm:GetParameter"], resources: [`arn:aws:ssm:${parameterStoreRegion}:${this.account}:parameter/COGNITO_CONFIG`], }) ); ``` Note: connection reuse must be false for Lambda@Edge compatibility, otherwise you'll see a warning during synth

Please note that this requires to manually prepare a stringified version of the configuration under a known key in the AWS Systems Manager Parameter Store. This is certainly not the only way to do that.

Please note that @aws-sdk/client-ssm and all @aws-sdk packages are only available by default in the Node.js 18+ AWS Lambda runtime.