#amazon-web-services #aws-lambda #graphql #aws-appsync
#amazon-web-services #aws-lambda #graphql #aws-appsync
Вопрос:
У меня возникли проблемы с вызовом запроса AppSync GraphQL с помощью функции AWS Lambda. Я использовал код в этой статье, в частности, последнюю часть, в которой используются разрешения IAM: https://docs.amplify.aws/lib/graphqlapi/graphql-from-nodejs/q/platform/js#signing-a-request-from-lambda
const https = require("https");
const AWS = require("aws-sdk");
const urlParse = require("url").URL;
const appsyncUrl = process.env.API_MYAPP_GRAPHQLAPIENDPOINTOUTPUT;
const region = process.env.REGION;
const endpoint = new urlParse(appsyncUrl).hostname.toString();
const graphqlQuery = require("./query.js").query;
exports.handler = async (event) => {
const req = new AWS.HttpRequest(appsyncUrl, region);
req.method = "POST";
req.path = "/graphql";
req.headers.host = endpoint;
req.headers["Content-Type"] = "application/json";
req.body = JSON.stringify({
query: graphqlQuery,
operationName: "list",
});
const signer = new AWS.Signers.V4(req, "appsync", true);
signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate());
const data = await new Promise((resolve, reject) => {
const httpRequest = https.request({ ...req, host: endpoint }, (result) => {
result.on("data", (data) => {
resolve(JSON.parse(data.toString()));
});
});
httpRequest.write(req.body);
httpRequest.end();
});
return {
statusCode: 200,
body: data,
};
};
Я использую CLI Amplify. Я использовал CLI для создания функции и обеспечения доступа к API GraphQL.
Конкретная ошибка, которую я получаю в лямбде, такова:
{
"statusCode": 200,
"body": {
"errors": [
{
"errorType": "UnauthorizedException",
"message": "Permission denied"
}
]
}
}
GraphQL настроен на использование пула пользователей Cognito в качестве аутентификации, и я добавил IAM в качестве дополнительного механизма аутентификации через CLI Amplify. Консоль AWS GraphQL показывает, что у меня есть Cognito в качестве основного механизма аутентификации, а IAM — вторичный.
Похоже, что функция Lambda разрешена нормально, поскольку она показывает 4 ресурса (создание, обновление, удаление, чтение), соответствующие API, и разрешает: appsync:GraphQL в качестве действия.
Если я запускаю функцию локально, используя amplify mock function myfunction
ее, она выполняется нормально, и результат запроса GraphQL возвращается правильно.
Я также могу успешно выполнить тот же запрос через интерфейс AppSync, когда я выбираю IAM в качестве механизма аутентификации.
Таблица, к которой я обращаюсь, определена в моем schema.graphql как:
type Business
@model
@auth(
rules: [
{ allow: owner }
{ allow: groups, groups: ["Admin"] }
{ allow: private, provider: iam }
]
) {
id: ID!
owner: String!
name: String!
emailSuffix: String!
shortCode: String!
}
Я удалил аутентификацию из модели, и это не имеет значения.
Я удалил функцию и заново создал ее на случай, если разрешения каким-то образом перепутались.
Так что я не думаю, что это код, похоже, ошибка разрешений. Я не понимаю, в чем может быть проблема
ОБНОВЛЕНИЕ Я внес изменения в политику разрешений внутри IAM Manager для политики amplify-lambda-execution, и это, похоже, устранило проблему.
Политика разрешений, первоначально добавленная Amplify, имела вид:
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/create/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/read/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/edit/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/delete/*
внесение изменений в:
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID/types/*/fields/*
arn:aws:appsync:MYREGION:MYID:apis/MYAPIID
позволяет функции lambda выполнить и успешно выполнить запрос GraphQL в моей таблице. Похоже, это проблема с разрешениями, которые Amplify добавляет к функции. Перезапись вручную не является отличным решением.
Ответ №1:
Проблема возникла после установки — amplify cli «4.45.2». Старый код для автоматически создаваемых разрешений в шаблоне lambda cloudformation выглядел следующим образом.
{
"Effect": "Allow",
"Action": [
"appsync:Create*",
"appsync:StartSchemaCreation",
"appsync:GraphQL",
"appsync:Get*",
"appsync:List*",
"appsync:Update*",
"appsync:Delete*"
],
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/*"
]
]
}
]
}
Но после того, как я перешел на усиление cli «4.45.2» и предоставил разрешения lambda для appsync.
Он сгенерировал :
{
"Effect": "Allow",
"Action": [
"appsync:GraphQL"
],
"Resource": [
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/types/create/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/types/read/*"
]
]
},
{
"Fn::Join": [
"",
[
"arn:aws:appsync:",
{
"Ref": "AWS::Region"
},
":",
{
"Ref": "AWS::AccountId"
},
":apis/",
{
"Ref": "myApiGraphQLAPIIdOutput"
},
"/types/update/*"
]
]
}
]
}
enter code here
И я получил сообщение об ошибке «отказано в разрешении» при попытке связаться с appsync из lambda.
Я думаю, что в новом cli есть какая-то ошибка при генерации разрешений appsync для lambda.
Я вручную вернулся к старому сгенерированному коду в файле lambda cloudformation, и это сработало.
Комментарии:
1. Спасибо, что поделились файлами формирования облака. Это полезно. Я использую 4.44.2 CLI Amplify. Я не обновился до 4.45.2. Должно быть, проблема с обеими версиями CLI. Обновление файла формирования облака вручную лучше, чем ручная настройка разрешений через пользовательский интерфейс.