amazon-web-services - 无法使用 Amazon Amplify 从 Lambda 调用 GraphQL

标签 amazon-web-services aws-lambda graphql aws-amplify aws-appsync

我正在使用 Amazon Amplify 创建一个访问 AppSync GraphQL 终端节点内容的函数。
我使用命令行创建了新函数和 API,并且可以从前端应用程序正确调用它,但是,我一直收到此错误:

2020-12-16T01:39:40.524Z    979abb8d-4d64-4929-937a-03b0cb495174    INFO    error posting to appsync:  Error: Request failed with status code 401
    at createError (/var/task/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/var/task/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/lib/adapters/http.js:244:11)
    at IncomingMessage.emit (events.js:326:22)
    at endReadableNT (_stream_readable.js:1223:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  config: {
    url: 'https://y63v24inqneirizeuiig7x5g54.appsync-api.us-east-1.amazonaws.com/graphql',
    method: 'post',
    data: '{"query":"query listCompetitions {\\n  listCompetitions {\\n    items {\\n      createdAt\\n      id\\n      likes\\n      updatedAt\\n      votes\\n      websiteImageKey\\n      websiteUrl\\n      user {\\n        username\\n        imageKey\\n      }\\n      websiteDescription\\n    }\\n  }\\n}\\n"}',
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json;charset=utf-8',
      'x-api-key': '7aeiasrvb5bczhmlt2nnbpfuyi',
      'User-Agent': 'axios/0.21.0',
      'Content-Length': 284
    },
我用来从我的函数中调用 GraphQL 的代码来自这个 link .
const graphqlData = await axios({
      url: process.env.API_MAINDATA_GRAPHQLAPIENDPOINTOUTPUT,
      method: "post",
      headers: {
        "x-api-key": process.env.API_MAINDATA_GRAPHQLAPIIDOUTPUT,
      },
      data: {
        query: print(listCompetition),
      },
    });
URL 和 KEY 是由 Amplify 添加到 env 中的,我已经为有问题的 API 添加了 API_KEY auth,所以我不明白为什么我仍然得到 401 error .
我注意到的一件事是该文件说要使用:'x-api-key': process.env.API_<YOUR_API_NAME>_GRAPHQLAPIKEYOUTPUT然而_GRAPHQLAPIKEYOUTPUT没有生成所以我使用 _GRAPHQLAPIIDOUTPUT相反,不确定这是否发生了变化,或者我是否缺少环境常量。

最佳答案

您是否正确签署了您的请求?退房 AWS.Signers.V4如果你还没有。
我遇到了和你类似的问题,我最终实现了一个专用的 Lambda 函数来执行 GraphQL 操作。这样,只要我想执行 GraphQL 操作,我就可以调用我的 Lambda 函数。
就像是:

/* Amplify Params - DO NOT EDIT
    API_XXXXXX_GRAPHQLAPIENDPOINTOUTPUT
    API_XXXXXX_GRAPHQLAPIIDOUTPUT
    ENV
    REGION
Amplify Params - DO NOT EDIT */

const AWS = require('aws-sdk')
const https = require('https')
const urlParse = require('url').URL

const APPSYNC_URL = process.env['API_XXXXXX_GRAPHQLAPIENDPOINTOUTPUT']
const REGION = process.env['REGION']

const ENDPOINT = new urlParse(APPSYNC_URL).hostname.toString()

//
// execute a graphql operation via appsync
//
exports.handler = async ({ item, operation, operationName }) => {
  const request = createSignedRequest(
    ENDPOINT,
    item,
    operation,
    operationName,
    REGION,
    APPSYNC_URL,
  )
  return getResponseFromApi(ENDPOINT, request)
}

//
// create a signed graphql operation request
//
const createSignedRequest = (
  endpoint,
  item,
  operation,
  operationName,
  region,
  url,
) => {
  const request = new AWS.HttpRequest(url, region)
  request.method = 'POST'
  request.path = '/graphql'
  request.headers.host = endpoint
  request.headers['Content-Type'] = 'application/json'
  request.body = JSON.stringify({
    query: operation,
    operationName: operationName,
    variables: item,
  })

  const signer = new AWS.Signers.V4(request, 'appsync', true)
  signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate())

  return request
}

//
// send a request to the appsync api and return the response data
//
const getResponseFromApi = (endpoint, request) => {
  return new Promise((resolve, reject) => {
    const httpRequest = https.request(
      { ...request, host: endpoint },
      (result) => {
        result.on('data', (data) => {
          resolve(JSON.parse(data.toString()))
        })
      },
    )
    httpRequest.write(request.body)
    httpRequest.end()
  })
}

关于amazon-web-services - 无法使用 Amazon Amplify 从 Lambda 调用 GraphQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65316214/

相关文章:

javascript - 如何将 AMAZON_COGNITO_USER_POOLS 与 apollo-client 一起使用

php - 无法从 AWS AMI 运行 FTP 命令

javascript - GraphQL 突变的响应应该是什么?

c# - Strawberry Shake 代码生成无法解析类型引用 'None:Any'

javascript - 在不同解析器上解析联合类型

amazon-web-services - Amazon S3 并行下载带宽

amazon-web-services - 通过 aws-sdk-go 签署 URL 时出现签名不匹配 403 错误

aws-lambda - 无法在 SAM 模板中添加策略

amazon-web-services - 如何运行 AWS Lambda 函数来让我知道 CloudFormation 已完成整个堆栈创建

typescript - 使用 Nest.js 在 AWS Lambda 中获取 Cognito 数据(即 requestContext)