我正在使用 AWS Lambda 授权 GraphQL 查询,我想使用授权令牌从 Cognito 获取客户端信息,并使用用户属性中的 sub 来检查用户是否在我的记录表中购买了手机,但每次我调用该方法时,它都会返回
BadRequestException: Unknown error at buildRestApiServiceError
。
架构:
type Phone
@model
@auth(rules: [{ allow: owner }, { allow: custom, operations: [read] }]) {
id: ID!
title: String!
description: AWSJSON!
rating: Float
}
AWS Lambda:
exports.handler = async (event) => {
console.log(`EVENT: ${JSON.stringify(event)}`);
const {
authorizationToken,
requestContext: { queryString },
} = event;
try {
const cognitoClient = new CognitoIdentityProviderClient({});
const cognitoInput = {
AccessToken: authorizationToken,
};
const cognitoCommand = new GetUserCommand(cognitoInput);
const user = await cognitoClient.send(cognitoCommand);
const dynamoClient = new DynamoDBClient({});
const dynamoInput = {
Key: {
id: {
S: user.Username,
},
},
TableName: "RecordTable",
};
const dynamoCommand = new GetItemCommand(dynamoInput);
const response = await dynamoClient.send(dynamoCommand);
let isPurchased = false;
for (let index = 0; index < purchasedPhones.length; index++) {
const phoneID = purchasedPhones[index];
if (queryString.includes(phoneID)) {
isPurchased = true;
break;
}
}
return {
isAuthorized: isPurchased,
resolverContext: {
userid: userId,
info: user,
more_info: response,
},
ttlOverride: 300,
};
} catch (error) {
return error;
}
};
GraphQL方法:
const phone = await client.graphql<GraphQLQuery<GetPhoneQuery>>({
query: getPhone,
authMode: "lambda",
authToken: "xxxxxxx...xxx",
variables: {
id,
},
});
功能概述:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: An AWS Serverless Application Model template describing your function.
Resources:
graphQlLambdaAuthorizer8c87c0ddbeta:
Type: AWS::Serverless::Function
Properties:
CodeUri: .
Description: ''
MemorySize: 128
Timeout: 25
Handler: index.handler
Runtime: nodejs18.x
Architectures:
- x86_64
EphemeralStorage:
Size: 512
Environment:
Variables:
ENV: beta
REGION: us-east-2
EventInvokeConfig:
MaximumEventAgeInSeconds: 21600
MaximumRetryAttempts: 2
Layers:
- arn:aws:lambda:us-east-2:580247275435:layer:LambdaInsightsExtension:45
PackageType: Zip
Policies:
- Statement:
- Effect: Allow
Action:
- lambda:InvokeFunction
Resource: >-
arn:aws:lambda:us-east-2:062633224221:function:graphQlLambdaAuthorizer8c87c0dd-beta
- Effect: Allow
Action:
- appsync:GraphQL
- appsync:GetGraphqlApi
- appsync:ListGraphqlApis
- appsync:ListApiKeys
Resource: '*'
- Effect: Allow
Action:
- cognito-identity:Describe*
- cognito-identity:Get*
- cognito-identity:List*
- cognito-idp:Describe*
- cognito-idp:AdminGet*
- cognito-idp:AdminList*
- cognito-idp:List*
- cognito-idp:Get*
- cognito-sync:Describe*
- cognito-sync:Get*
- cognito-sync:List*
- iam:ListOpenIdConnectProviders
- iam:ListRoles
- sns:ListPlatformApplications
Resource: '*'
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource: '*'
- Effect: Allow
Action:
- xray:PutTraceSegments
- xray:PutTelemetryRecords
Resource:
- '*'
- Action:
- dynamodb:DeleteItem
- dynamodb:GetItem
- dynamodb:BatchGetItem
- dynamodb:PutItem
- dynamodb:Query
- dynamodb:Scan
- dynamodb:UpdateItem
Resource:
- arn:aws:dynamodb:us-east-2:062633224221:table/RecordTable
Effect: Allow
Sid: AllowDynamoDB
SnapStart:
ApplyOn: None
Tags:
user:Application: XXXXX
user:Stack: beta
Tracing: Active
Events:
Api1:
Type: Api
Properties:
Path: /MyResource
Method: ANY
RuntimeManagementConfig:
UpdateRuntimeOn: Auto
我不太确定我在这里错过了什么。
我认为你遗漏了一些要点。您似乎正在尝试使用 AWS AppSync 和 AWS Lambda 为手机型号实现授权逻辑。
检查 IAM 角色和权限
验证授权令牌
调试和 DynamoDB 交互
错误处理
GraphQL 查询执行
我希望这有帮助;)
该错误通常是由于 lambda 授权者的返回对象中的拒绝字段造成的。 DeniedFields 是一个数组,应包含您不允许用户进行的所有字段、突变和查询。在您的情况下,lambda 授权者授权了该请求,但不允许您发出的特定请求,我认为是因为您没有返回拒绝字段数组 - https://aws.amazon.com/blogs/mobile/appsync-lambda-授权/.
例如,返回一个空的deniedFields数组,它将起作用。 DeniedFeilds 的全部目的是让您对每个用户可以看到的内容进行细粒度控制。
此外,如果您要在 lambda 授权者中调用 Cognito API,特别是如果您仅缓存响应 5 分钟,我会检查 Cognito API 配额。