
[英]Can I conditionally invoke a lambda function in an AWS Appsync resolver?
[英]How can I use IAM to invoke AppSync wtihin AWS Lambda?
我目前正在使用 AppSync 在 AWS Lambda 中實施訂閱突變。 我想使用 IAM 並避免使用任何其他類型的 AUTH 機制,因為我在 AWS 堆棧中調用它。 不幸的是,我收到以下 403 錯誤:
(摘自 SQS 的 CloudWatch 日志)
{
"errorMessage": "Response not successful: Received status code 403",
"name": "ServerError",
"errorType": "UnrecognizedClientException",
"message": "The security token included in the request is invalid."
}
我試過遵循這些無濟於事,但我不知道我錯過了什么:
這是我當前調用它的代碼:
import AWS from "aws-sdk";
import { AWSAppSyncClient } from "aws-appsync";
import { Mutation, mutations } from "./mutations/";
import "cross-fetch/polyfill";
/**
*
*/
AWS.config.update({
region: Config.region,
});
export class AppSyncClient {
client: AWSAppSyncClient<any>;
constructor() {
if (!env.APPSYNC_ENDPOINT) {
throw new Error("APPSYNC_ENDPOINT not defined");
}
/**
* We create the AppSyncClient with the AWS_IAM
* authentication.
*/
this.client = new AWSAppSyncClient({
url: env.APPSYNC_ENDPOINT,
region: Config.region,
auth: {
credentials: AWS.config.credentials!,
type: "AWS_IAM",
},
disableOffline: true,
});
}
/**
* Sends a mutation on the AppSync Client
* @param mutate The Mutation that will be sent with the variables.
* @returns
*/
sendMutation(mutate: Mutation) {
const mutation = mutations[mutate.type] as any;
const variables = mutate.variables;
console.log("Sending the mutation");
console.log("Variables is ", JSON.stringify(variables));
return this.client.mutate({
mutation,
fetchPolicy: "network-only",
variables,
});
}
}
這是來自 Lambda SQS 的當前 IAM:
{
"Statement": [
{
"Action": [
"appsync:GraphQL"
],
"Effect": "Allow",
"Resource": [
"arn:aws:appsync:us-east-2:747936726382:apis/myapi"
]
}
],
"Version": "2012-10-17"
}
我知道這不是來自 lambda 的 IAM 問題,因為我已經嘗試暫時授予它完全訪問權限,但仍然出現 403 錯誤。
我還驗證了 AppSync 配置了 IAM 權限(作為附加提供者)。
你們有什么想法嗎? 我印象深刻的是,這是一個幾乎沒有配置參考的鬼主題。
我終於搞定了。 我第三次去重讀了Adrian Hall 的帖子,它確實讓我找到了解決方案。
請注意,我安裝了不需要但簡化了流程的 AWS AppSync 客戶端(否則您必須自己簽署 URL。有關詳情,請參閱 Adrian Hall 的帖子)。
有幾件事:
cross-fetch
來填充“提取”(否則您將受到來自 AppSync 內部使用的 Apollo 客戶端的不變違規的影響)。["appsync:GraphQL"]
用於操作。這是一些代碼:
這是 AppSync 代碼。
// The code is written in TypeScript.
// https://adrianhall.github.io/cloud/2018/10/26/backend-graphql-trigger-appsync/
// https://www.edwardbeazer.com/using-appsync-client-from-lambda/
import { env } from "process";
import { Config, env as Env } from "../../../../shared";
// This is such a bad practice
import AWS from "aws-sdk";
import { AWSAppSyncClient } from "aws-appsync";
import { Mutation, mutations } from "./mutations/";
// Very important, otherwise it won't work!!! You'll have Invariant Violation
// from Apollo Client.
import "cross-fetch/polyfill";
/**
*
*/
AWS.config.update({
region: Config.region,
credentials: new AWS.Credentials(
env.AWS_ACCESS_KEY_ID!,
env.AWS_SECRET_ACCESS_KEY!,
env.AWS_SESSION_TOKEN!
),
});
export class AppSyncClient {
client: AWSAppSyncClient<any>;
constructor() {
// Your AppSync endpoint - The Full URL.
if (!Env.APPSYNC_ENDPOINT) {
throw new Error("APPSYNC_ENDPOINT not defined");
}
/**
* We create the AppSyncClient with the AWS_IAM
* authentication.
*/
this.client = new AWSAppSyncClient({
url: Env.APPSYNC_ENDPOINT,
region: Config.region,
auth: {
credentials: AWS.config.credentials!,
type: "AWS_IAM",
},
disableOffline: true,
});
}
/**
* Sends a mutation on the AppSync Client
* @param mutate The Mutation that will be sent with the variables.
* @returns
*/
// The mutation is a object that holds the mutation in
// the `gql` tag. You can ommit this part.
sendMutation(mutate: Mutation) {
const mutation = mutations[mutate.type] as any;
const variables = mutate.variables;
// This is the important part.
return this.client.mutate({
mutation,
// Specify "no-cache" in the policy.
// network-only won't work.
fetchPolicy: "no-cache",
variables,
});
}
}
我們需要在 AppSync 授權機制中啟用 IAM。 是的,可以啟用多個身份驗證。 我目前正在同時使用 OPEN_ID 和 IAM。
https://us-east-2.console.aws.amazon.com/appsync/home?region=us-east-2#/myappsync-id/v1/settings
這是執行 GQL 的 Lambda IAM 策略:
{
"Statement": [
{
"Action": [
"appsync:GraphQL"
],
"Effect": "Allow",
"Resource": [
"arn:aws:appsync:us-east-2:747936726382:apis/ogolfgja65edlmhkcpp3lcmwli/*"
]
}
],
"Version": "2012-10-17"
}
您可以通過以下方式進一步限制此處: arn:${Partition}:appsync:${Region}:${Account}:apis/${GraphQLAPIId}/types/${TypeName}/fields/${FieldName}
arn:aws:appsync:us-east-2:747936726382:apis/ogolfgja65edlmhkcpp3lcmwli/types/Mutation/field/myCustomField"
請注意,我們需要更好地限制這一點,因為我們目前授予它對 API 的完全訪問權限。
在 your.gql 文件(AppSync GraphQL 架構)中,將 @aws_iam 指令添加到用於將訂閱發送到的突變中,以限制來自前端的訪問。
type Mutation {
addUsersMutationSubscription(
input: AddUsersSagaResultInput!
): AddUsersSagaResult @aws_iam
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.