I'm using an AWS Lambda to authorize a GraphQL query, I want to use the authorization token to get the client information from Cognito, and use the sub in the user attributes to check if the user purchased a phone in my Record Table, but every time I call the method it returns BadRequestException: Unknown error at buildRestApiServiceError.
Schema:
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 method:
const phone = await client.graphql<GraphQLQuery<GetPhoneQuery>>({
query: getPhone,
authMode: "lambda",
authToken: "xxxxxxx...xxx",
variables: {
id,
},
});
Function Overview:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "{\"createdOn\":\"Windows\",\"createdBy\":\"Amplify\",\"createdWith\":\"12.10.1\",\"stackType\":\"function-Lambda\",\"metadata\":{}}",
"Parameters": {
"CloudWatchRule": {
"Type": "String",
"Default": "NONE",
"Description": " Schedule Expression"
},
"deploymentBucketName": {
"Type": "String"
},
"env": {
"Type": "String"
},
"s3Key": {
"Type": "String"
}
},
"Conditions": {
"ShouldNotCreateEnvResources": {
"Fn::Equals": [
{
"Ref": "env"
},
"NONE"
]
}
},
"Resources": {
"LambdaFunction": {
"Type": "AWS::Lambda::Function",
"Metadata": {
"aws:asset:path": "./src",
"aws:asset:property": "Code"
},
"Properties": {
"Code": {
"S3Bucket": {
"Ref": "deploymentBucketName"
},
"S3Key": {
"Ref": "s3Key"
}
},
"Handler": "index.handler",
"FunctionName": {
"Fn::If": [
"ShouldNotCreateEnvResources",
"graphQlLambdaAuthorizer364c8848",
{
"Fn::Join": [
"",
[
"graphQlLambdaAuthorizer364c8848",
"-",
{
"Ref": "env"
}
]
]
}
]
},
"Environment": {
"Variables": {
"ENV": {
"Ref": "env"
},
"REGION": {
"Ref": "AWS::Region"
}
}
},
"Role": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
},
"Runtime": "nodejs18.x",
"Layers": [],
"Timeout": 25
}
},
"LambdaExecutionRole": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": {
"Fn::If": [
"ShouldNotCreateEnvResources",
"testLambdaRoleb7fb041f",
{
"Fn::Join": [
"",
[
"testLambdaRoleb7fb041f",
"-",
{
"Ref": "env"
}
]
]
}
]
},
"AssumeRolePolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com"
]
},
"Action": [
"sts:AssumeRole"
]
}
]
}
}
},
"lambdaexecutionpolicy": {
"DependsOn": [
"LambdaExecutionRole"
],
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyName": "lambda-execution-policy",
"Roles": [
{
"Ref": "LambdaExecutionRole"
}
],
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
}
},
"PermissionForAppSyncToInvokeLambda": {
"Type": "AWS::Lambda::Permission",
"Properties": {
"FunctionName": {
"Ref": "LambdaFunction"
},
"Action": "lambda:InvokeFunction",
"Principal": "appsync.amazonaws.com"
}
}
},
"Outputs": {
"Name": {
"Value": {
"Ref": "LambdaFunction"
}
},
"Arn": {
"Value": {
"Fn::GetAtt": [
"LambdaFunction",
"Arn"
]
}
},
"Region": {
"Value": {
"Ref": "AWS::Region"
}
},
"LambdaExecutionRole": {
"Value": {
"Ref": "LambdaExecutionRole"
}
},
"LambdaExecutionRoleArn": {
"Value": {
"Fn::GetAtt": [
"LambdaExecutionRole",
"Arn"
]
}
}
}
}
I'm not quite sure what I'm missing here.
i think you have been missing some points. It looks like your trying to implement authorisation logic for a phone model using AWS AppSync and AWS Lambda.
Check the IAM roles and permissions
verify the authorisation token
Debugging and DynamoDB interaction
Error hadndling
GraphQL query execution
i hope this helps ;)