首页 > 解决方案 > 在 Amazon AWS 上获取一个简单的 Symfony 5 应用程序作为 Amazon Cognito 的 API 网关/Lambda

问题描述

这可能涉及太多特定技术,任何人都无法回答,但我想我会试一试。我已经准备好了很多教程,感觉我已经很接近了……我可能只缺少一件事。

我的目标是多部分的,据我所知,我的问题目前只有一个部分

现在,在有关如何将 bref 与 AWS 一起使用的单个文件 PHP 示例中,您会得到如下内容:


require __DIR__.'/vendor/autoload.php';

lambda(function ($event) {
    return $event;
});

我已经将它作为一个不同的 lambda 上传(这里与 Symfony 无关),将其设置为 Cognito 的预注册事件的触发器,它工作正常。它什么都不做,但它会将信息正确地传递到不会导致任何类型错误的地方。

现在,当我用 Symfony 应用程序尝试同样的事情时,我的 src/Controller 目录中有 IndexController.php,如下所示:

<?php

namespace App\Controller;

use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Aws\CloudWatchLogs\CloudWatchLogsClient;
use Maxbanton\Cwh\Handler\CloudWatch;
use Monolog\Logger;
use Monolog\Formatter\JsonFormatter;

class IndexController extends AbstractController
{
    /**
     * @Route("/", name="index")
     */
    public function index(Request $request, LoggerInterface $logger)
    {
        $this->awsLogger($request);
        return new JsonResponse(json_encode($request->query->all()));
    }

    private function awsLogger(Request $request)
    {
        /**
         * This is only here for now because I couldn't get CloudWatch logging working any better way.
         */
        $sdkParams = [
            'region' => 'us-east-2',
            'version' => 'latest',
            'credentials' => [
                'key' => 'AKIAIGFNOM3BKSE6HQ6A',
                'secret' => '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',
            ]
        ];

        // Instantiate AWS SDK CloudWatch Logs Client
        $client = new CloudWatchLogsClient($sdkParams);

        // Log group name, will be created if none
        $groupName = 'lambda_symfony_test';

        // Log stream name, will be created if none
        $streamName = 'dev';

        // Days to keep logs, 14 by default. Set to `null` to allow indefinite retention.
        $retentionDays = 30;

        // Instantiate handler (tags are optional)
        $handler = new CloudWatch($client, $groupName, $streamName, $retentionDays, 10000, ['tag' => 'lambda']);

        // Optionally set the JsonFormatter to be able to access your log messages in a structured way
        $handler->setFormatter(new JsonFormatter());

        // Create a log channel
        $log = new Logger('channel');

        // Set handler
        $log->pushHandler($handler);

        // Add records to the log
        $log->debug(print_r($request->query->all(), true));
    }
}

我完全理解这会导致 lambda 错误,因为 JsonResponse 不是 Cognito 期望看到的。然而,我至少希望我能够调用记录器,这样我就可以看到我的请求对象是什么样子的,并且我可以看到我正在处理的内容,即 Cognito 传递给这个 Lambda 的内容。这将帮助我最终弄清楚我需要返回什么。据我所知,我不能只在控制器方法周围使用“lambda”包装器,就像我提到的我工作过的简单示例中所做的那样。然而,它甚至没有走到这一步,相反,以下是我在 CloudWatch 上的日志中出现的内容:

21:34:58
Fatal error: Uncaught Exception: The lambda was not invoked via HTTP through API Gateway: this is not supported by this runtime in /var/task/vendor/bref/bref/src/Runtime/PhpFpm.php:120

所以我的问题是我在这里错过了什么?当我将它作为 GET 请求传递时,这个 API 通过浏览器完全可以正常工作。我的配置中缺少什么?这是我的 Symfony 应用程序的 serverless.yml 文件:

service: lambda-test-symfony

provider:
  name: aws
  region: us-east-2
  runtime: provided
  environment:
    # Symfony environment variables
    APP_ENV: prod

plugins:
  - ./vendor/bref/bref

package:
  exclude:
    - node_modules/**
    - tests/**

functions:
  lambdatest:
    handler: public/index.php
    layers:
      - ${bref:layer.php-72-fpm}
    events:
      -   http: 'ANY /'
      -   http: 'ANY /{proxy+}'

以下是我在 AWS 上的 Lambda 配置的一些截图:

https://i.stack.imgur.com/TDMZj.png

https://i.stack.imgur.com/ciehT.png

以下是 API 网关设置中的一些内容:

https://i.stack.imgur.com/RL7D9.png

https://i.stack.imgur.com/LPcsh.png

https://i.stack.imgur.com/RVNwN.png

https://i.stack.imgur.com/4bs0u.png

我对整个 AWS/无服务器的东西还很陌生,所以我可能在这里遗漏了一些非常明显的东西。我不是 100% 确定问题出在我的代码还是我的配置上。任何帮助,将不胜感激!

标签: symfonyaws-lambdaaws-api-gatewayamazon-cognito

解决方案


推荐阅读