Aws-sdk-js: Trying to trigger AppSync query via lambda function. V4 signer.addauthorization not working. Error message: "Data must be a string or a buffer"

Created on 23 Nov 2018  路  11Comments  路  Source: aws/aws-sdk-js

Error Message
2018-11-23T14:37:03.533Z 3e0ff525-ef2d-11e8-8328-89b33f69a07f TypeError: Data must be a string or a buffer at Hmac.update (crypto.js:99:16) at Object.hmac (/var/task/node_modules/aws-sdk/lib/util.js:399:50) at Object.getSigningKey (/var/task/node_modules/aws-sdk/lib/signers/v4_credentials.js:74:35) at V4.signature (/var/task/node_modules/aws-sdk/lib/signers/v4.js:98:36) at V4.authorization (/var/task/node_modules/aws-sdk/lib/signers/v4.js:93:36) at V4.addAuthorization (/var/task/node_modules/aws-sdk/lib/signers/v4.js:35:12) at AWS.config.credentials.get.err (/var/task/index.js:52:10) at Credentials.get (/var/task/node_modules/aws-sdk/lib/credentials.js:126:7) at exports.handler (/var/task/index.js:42:25) END RequestId: 3e0ff525-ef2d-11e8-8328-89b33f69a07f REPORT RequestId: 3e0ff525-ef2d-11e8-8328-89b33f69a07f Duration: 103.19 ms Billed Duration: 200 ms Memory Size: 128 MB Max Memory Used: 60 MB RequestId: 3e0ff525-ef2d-11e8-8328-89b33f69a07f Process exited before completing request

Expected result
The V4 signing should complete successfully.

Current result
it currently fails with the error message above. I did some digging, in the hmac function in util.js, and realized that it gets called 3 times while the lambda function runs.
I only call signer.addAuthorization(cred, date) once.

the first 2 times hmac gets called, it has a correct string parameter, which allows the successful creation of a buffer used in the function to create a new hmac, and return it.

the third time, this string parameter is false. Thus, the Buffer isn't created, and the hmac.update(string) function fails with the error indicated above.

any help? Could this be a result of something I'm doing wrong?

guidance

Most helpful comment

In case it helps somebody...I had the same problem and the origin of it was that the region environment variable was empty ( I was typing env.REGION when mine was defined in lowercase: env.region)

All 11 comments

@hagiosofori

Thanks for opening this issue.

Could you provide an example of the AppSync query you are performing?

Are you supplying your own version of the SDK in Lambda? What version? What Lambda runtime are you using?

@srchase
the query I'm running
```AWS.config.update({
region: env.AWS_REGION,
credentials: new AWS.Credentials(
env.AWS_ACCESS_KEY_ID,
env.AWS_SECRET_ACCESS_KEY,
env.AWS_SESSION_TOKEN
),
})

exports.handler = function(event, context, callback) {
//eslint-disable-line
const requestBody = {
query: ListSources,
operationName: "ListSources",
}
console.log(posting ${JSON.stringify(requestBody, null, 2)})
console.log('check')
const uri = URL.parse(config.graphqlEndpoint)
const httpRequest = new AWS.HttpRequest(uri.href, env.REGION)
httpRequest.headers.host = uri.host
httpRequest.headers["Content-Type"] = "application/json"
httpRequest.method = "GET"
httpRequest.body = JSON.stringify(requestBody)

console.log(`http request: ${JSON.stringify(httpRequest)}`)

AWS.config.credentials.get(err => {
    const signer = new AWS.Signers.V4(httpRequest, "appsync", true)

    console.log(`signer: ${JSON.stringify(signer)}`)
    const date = AWS.util.date.getDate()
    const isodate = date.toISOString()

    console.log(`credentials: ${JSON.stringify(AWS.config.credentials)}`)
    console.log(typeof isodate)

    signer.addAuthorization(AWS.config.credentials, AWS.util.date.getDate())
    console.log(`not signer.addauthentication`)
    const options = {
        method: httpRequest.method,
        body: httpRequest.body,
        headers: httpRequest.headers,
    }

    fetch(uri.href, options)
        .then(res => res.json())
        .then(json => {
            console.log(`JSON Response = ${JSON.stringify(json, null, 2)}`)
            callback(null, event)
        })
})

callback(null, event)
//fetch the appropriate source盲, with the source fields

}

actual query
ListSources = `query ListSources{ listSources{ items{ id name url isActive fields{ items{ name id selector isActive } } } } }

Query version
2.361.0

I pulled it from npm, for use in the application. I've made no modifications to it

Thank you...

lambda runtime
Node 8.10

I am encountering the same issue in an almost identical use case, when removing the signer.addAuthorization the call is successfully gets a not authenticated response, so the request is being sent correctly.

@hagiosofori

Refer to @chrisradek's comment on an earlier issue: https://github.com/aws/aws-sdk-js/issues/1247#issuecomment-264285589

Also, check out SignatureV4 in v3 of the SDK. v3 is in preview, but would be a good solution once it's ready for production use.

thanks @srchase ... will check it out

I'll close this issue for now. If you have a followup, let us know and we can reopen.

Same problem here - almost same code for the signing part. Also the signing part is used in tons of blogs, etc. So did anyone actually manage to use it?

In case it helps somebody...I had the same problem and the origin of it was that the region environment variable was empty ( I was typing env.REGION when mine was defined in lowercase: env.region)

I'm also facing this problem @srchase. I'm trying to follow this gist.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

Was this page helpful?
0 / 5 - 0 ratings