0

我是一名 QA 工程师,希望自动化我们的超出 AWS 网关的 graphql API。我想使用 Javascripts 来实现这一点。经过研究,我确实意识到我们需要使用 AWS 访问密钥和 AWS 密钥生成 AWS 签名。我正在使用aws4npm 包生成 AWS 签名并graphql-request作为 graphql 的 Javascript 客户端。我正在尝试使用 appsync URL 查询我们的 graphql API。在执行时使用测试框架写在下面的代码中Javascript mocha,它返回了一个错误说Error: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

我确实尝试使用postman桌面客户​​端使用 AWS 签名查询 graphql API 并且工作正常,得到预期的输出!如果我手动使用authentication headers邮递员请求中的相同内容,它会在以编程方式执行时失败!

在此处欣赏任何想法或解决方案,以解决使用 AWS 签名查询 graphl API 的问题。

var assert = require('assert');
var http = require('https');
var aws4 = require('aws4');
const { GraphQLClient, gql } = require("graphql-request");
var crypto = require('crypto')


describe('Array', function () {

    
    var amzDate = getAmzDate(new Date().toISOString());
    // this function converts the generic JS ISO8601 date format to the specific format the AWS API wants
    function getAmzDate(dateStr) {
        var chars = [":", "-"];
        for (var i = 0; i < chars.length; i++) {
            while (dateStr.indexOf(chars[i]) != -1) {
                dateStr = dateStr.replace(chars[i], "");
            }
        }
        dateStr = dateStr.split(".")[0] + "Z";
        return dateStr;
    }

    describe('GetUser status ()', function () {
        it('should return the status of the User', async function () {
            const query = gql`
              { 
                getUser(userId: "d8a51af2453") {
                  status
                }
              }
              `
            // get the request body hash
            const getHash = crypto.createHash('sha256').update(query).digest('hex')
            console.log(getHash);

            // aws4 will sign an options object as you'd pass to http.request, with an AWS service and region
            var opts = { service: 'appsync', region: 'eu-west-1' }

            // aws4.sign() will sign and modify these options, ready to pass to http.request
            var awsauth = aws4.sign(opts, { accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY })
            var awsAuthHeaders = awsauth.headers.Authorization;
            console.log(awsauth);

            const graphQLClient = new GraphQLClient('https://<uniqueId>.appsync-api.eu-west-1.amazonaws.com/graphql', { headers: { authorization: awsAuthHeaders, 'X-Amz-Date': amzDate, 'X-Amz-Content-Sha256': getHash }, });
            console.log(graphQLClient);

            const data = await graphQLClient.request(query)
            console.log(JSON.stringify(data))

        });


    });
});

GraphQLClient控制台输出示例如下所示:

GraphQLClient {
  url: 'https://<uniqueId>.appsync-api.eu-west-1.amazonaws.com/graphql',
  options: {
    headers: {
      authorization: 'AWS4-HMAC-SHA256 Credential=AKIARASBW/20211005/eu-west-1/appsync/aws4_request, SignedHeaders=host;x-amz-date, Signature=d4a02fe6f6c3be5c5d2f6d6e19e4b32fd88ad0f3a0c',
      'X-Amz-Date': '20211005T133243Z',
      'X-Amz-Content-Sha256': 'f6b32c10d7968ce5b73783b77564d2c8'
    }
  }
}

Complete Error Message

Error: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.

The Canonical String for this request should have been
'POST
/graphql

host:<uniqueId>.appsync-api.eu-west-1.amazonaws.com
x-amz-date:20211005T133243Z

host;x-amz-date
abbabb07714cac737137d952f0f5eb59807'

The String-to-Sign should have been
'AWS4-HMAC-SHA256
20211005T133243Z
20211005/eu-west-1/appsync/aws4_request
3b8858c0ac56f03c47b6ab08b68445'
: {"response":{"errors":[{"errorType":"BadRequestException","message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'POST\n/graphql\n\nhost:<uniqueId>.appsync-api.eu-west-1.amazonaws.com\nx-amz-date:20211005T133243Z\n\nhost;x-amz-date\nabbabb07714cac737137d952f0f5eb5980e559113979727ce4'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20211005T133243Z\n20211005/eu-west-1/appsync/aws4_request\c70829ce6a36f62b673'\n"}],"status":400,"headers":{}},"request":{"query":"\n    {\n        getUser(userId: \"e8213d09-cdfd-94a7-ae07-cd8a51af2453\") {\n            status\n      }\n    }\n  "}}
      at node_modules/graphql-request/dist/index.js:254:31
      at step (node_modules/graphql-request/dist/index.js:63:23)
      at Object.next (node_modules/graphql-request/dist/index.js:44:53)
      at fulfilled (node_modules/graphql-request/dist/index.js:35:58)
      at processTicksAndRejections (internal/process/task_queues.js:97:5)

References

  1. aws4 签名生成参考来自https://www.npmjs.com/package/aws4中列出的示例
  2. Graphql Javascript 客户端从列表中选择https://graphql.org/code/#javascript
  3. 来自使用部分的 GraphQLCLient https://www.npmjs.com/package/graphql-request
4

0 回答 0