symfony - 在 Amazon AWS 上获取一个简单的 Symfony 5 应用程序作为 Amazon Cognito 的 API 网关/Lambda
问题描述
这可能涉及太多特定技术,任何人都无法回答,但我想我会试一试。我已经准备好了很多教程,感觉我已经很接近了……我可能只缺少一件事。
我的目标是多部分的,据我所知,我的问题目前只有一个部分
- 以一个带有单个控制器的简单 Symfony 应用程序(它恰好使用版本 5)为例,将其作为 API 网关放在 Amazon AWS 上。我在 bref ( https://bref.sh/ ) 的帮助下完成了这项工作,并在我的 Symfony 项目中需要它。我有一个 serverless.yml 文件,我可以使用 serverless deploy 命令将其作为 API 网关上传到 AWS。它甚至在浏览器中测试,没问题。
- 获取该 API 网关并将其链接到 AWS Lambda 函数,最终用作 Lambda 函数,以便在登录等时使用 Amazon Cognito 触发事件。我已经使用教程实现了这一点,当我进入我在步骤 1 中使用 bref 上传的 Lambda 函数时,我可以看到它链接到 API 网关。
- 获取此 Lambda 并将其链接到 Cognito 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% 确定问题出在我的代码还是我的配置上。任何帮助,将不胜感激!
解决方案
推荐阅读
- asp.net-core - 获取 AD 用户 Visual Studio Web App 与控制台
- javascript - jquery-ui 和 bootstrap offcanvas 的问题
- reactjs - Apollo Client:访问自定义钩子内的钩子函数调用变量?
- python - 使用 Iris 数据集的最后 20 个在 python 中断言
- c - 真正的入口点是动态加载程序中的 Linux 程序吗?如何在调用堆栈中显示它?
- javascript - 使用本机反应减少firebase中的值
- python - 所以我在 python 中制作了一个简单的计算器,一切正常,但我无法退出循环?
- python - Python BFS 程序不返回网格和路径,在有障碍和解决方案的迷宫中
- reactjs - 对所选链接 gastby styled-component 的影响
- node.js - 我需要允许用户使用他们的 Microsoft 电子邮件注册/登录我的应用程序(并基于在我的数据库中为他们创建的帐户)