You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS CloudFront搭配Lambda@Edge访问报502错误求助排查

问题:CloudFront集成Lambda@Edge返回502错误

我尝试用AWS S3、CloudFront和Lambda@Edge搭建带访问保护的前端(暂不集成Cognito),CDK部署正常,Lambda单独测试没问题,但加上Lambda后访问返回502错误,移除Lambda则前端正常访问。

CDK栈代码

export class MainStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const siteName = "mySite";

    const bucket = new s3.Bucket(this, "frontend", {
      bucketName: `${cdk.Stack.of(this).stackName.toLowerCase()}-${siteName}-frontend`,
      blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
      accessControl: s3.BucketAccessControl.PRIVATE,
      enforceSSL: true,
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      autoDeleteObjects: true,
      publicReadAccess: false,
    });
    new CfnOutput(this, "Bucket", { value: bucket.bucketName });

    const authFunction = new cloudfront.experimental.EdgeFunction(
      this,
      "authFunction",
      {
        handler: "authorizer.handler",
        runtime: lambda.Runtime.NODEJS_20_X,
        code: lambda.Code.fromAsset("src/lambdas/authorizer.zip"),
        currentVersionOptions: {
          removalPolicy: cdk.RemovalPolicy.DESTROY,
        },
        timeout: cdk.Duration.seconds(5),
      },
    );

    const distribution = new cloudfront.Distribution(
      this,
      "frontendCloudfrontDistribution",
      {
        defaultRootObject: "index.html",
        minimumProtocolVersion: cloudfront.SecurityPolicyProtocol.TLS_V1_2_2021,
        defaultBehavior: {
          origin: origins.S3BucketOrigin.withOriginAccessControl(bucket),
          compress: true,
          allowedMethods: cloudfront.AllowedMethods.ALLOW_GET_HEAD,
          viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.ALLOW_ALL,
          cachePolicy: CachePolicy.CACHING_DISABLED,
          edgeLambdas: [
            {
              functionVersion: authFunction.currentVersion,
              eventType: LambdaEdgeEventType.VIEWER_REQUEST,
            },
          ],
        },
      },
    );
    new CfnOutput(this, "DistributionId", {
      value: distribution.distributionId,
    });

    new s3deploy.BucketDeployment(this, "DeployWithInvalidation", {
      sources: [s3deploy.Source.asset(path.join(__dirname, "../frontend"))],
      destinationBucket: bucket,
      distribution,
      distributionPaths: ["/*"],
    });
  }
}

访问返回的502错误

502 ERROR

The request could not be satisfied.

The Lambda function returned an invalid request or response to CloudFront. We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.

If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.

现用Lambda代码

exports.handler = async (event, context, callback) => {
  const authorizationHeader = event?.request?.headers?.authorization;
  const preferredAuthorization = "Basic someBase64String";

  if (authorizationHeader?.value === preferredAuthorization) {
    console.log("Logged in");
    return event.request;
  }

  console.log("Unauthorized");
  return {
    statusCode: 401,
    statusDescription: "Unauthorized",
    headers: {
      "www-authenticate": [{ value: 'Basic realm="Enter your credentials"' }],
    },
  };
};

解决方案

你的Lambda@Edge代码存在两个关键格式错误,导致CloudFront无法解析响应,返回502:

  • 验证通过时返回对象错误
    Viewer Request类型的Lambda@Edge函数,允许请求继续时必须返回完整的event对象,而非仅event.request。CloudFront需要完整事件上下文处理后续流程,仅返回request部分会触发解析失败。

  • 拒绝响应的Headers格式不符合要求
    Lambda@Edge要求拒绝响应的headers每个条目必须包含key和value字段:

    • key为HTTP头标准名称(需符合大小写规范,如WWW-Authenticate)
    • value为头的具体内容

修正后的Lambda代码如下:

exports.handler = async (event) => {
  const authorizationHeader = event?.request?.headers?.authorization;
  const preferredAuthorization = "Basic someBase64String";

  if (authorizationHeader?.value === preferredAuthorization) {
    console.log("Logged in");
    // 验证通过,返回完整event对象
    return event;
  }

  console.log("Unauthorized");
  // 返回符合格式的拒绝响应
  return {
    statusCode: 401,
    statusDescription: "Unauthorized",
    headers: {
      "www-authenticate": [
        {
          key: "WWW-Authenticate",
          value: 'Basic realm="Enter your credentials"'
        }
      ]
    }
  };
};

另外,由于使用async函数,无需传入callback参数,直接return结果即可。部署修正后的Lambda@Edge版本后,记得触发CloudFront缓存失效,确保新函数版本生效。

内容的提问来源于stack exchange,提问作者Yorian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 11:37:13