Rich Steinmetz
Rich Steinmetz

Reputation: 1291

Getting 502 response and 'has been blocked by CORS policy' running a simple fetch request to my lambda function

Building a serverless web app on AWS with the serverless framework, I get a CORS error with a 502 response code authenticating against an AWS Cognito user pool

GET https://URL.amazonaws.com/dev/asset/ID-1178 502
index.html:1 Access to fetch at 'https://URL.amazonaws.com/dev/asset/PO-TIENDA1178' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
index.js:109 Uncaught (in promise) TypeError: Failed to fetch

An almost identical request works for another function.

And here are both ajax requests sent from the frontend:


// working just fine

        async function getAllAssets() {
            const getAssetsUrl = _config.api.invokeUrl + "/assets"
            const response = await fetch(getAssetsUrl, {
                headers: { 
                    Authorization: authToken
                },
                type: "GET",
                dataType: 'json',
                crossDomain: true
            })
        }

// not working, throwing the error described above

        async function getOneAsset() {
            const getAssetsUrl = _config.api.invokeUrl + "/asset/" + "ID-1178"
            const response = await fetch(getAssetsUrl, {
                headers: { 
                    Authorization: authToken
                },
                type: "GET",
                dataType: 'json',
                crossDomain: true
            })
        }

I run both functions onDocReady in the same window.

Here are the definitions in serverless.yaml:

  # WORKS 👌🏽
  getAssets:
    name: ${self:service}-${self:provider.stage}-get-assets
    handler: handler.getAssets
    role: InventoryLambdaRole
    events:
      - http:
          path: /assets
          method: get
          cors: true
          authorizer:
            arn: arn:aws:cognito-idp:eu-west-1:HARDCODED:ARN

  # doesn't work

  getAsset:
    name: ${self:service}-${self:provider.stage}-get-asset
    handler: handler.getAsset
    role: InventoryLambdaRole
    events:
      - http:
          path: /asset/{assetId}
          method: get
          cors: true
          authorizer:
            arn: arn:aws:cognito-idp:eu-west-1:HARDCODED:ARN

And here goes my function implementations in the handler.js:


// get all assets works fine:

module.exports.getAssets = function(event, context, callback) {
  const params = {
    TableName : 'Assets',
    Select: 'ALL_ATTRIBUTES',
  }

  const request = documentClient.scan(params, function(err, data) {
    if (err) {
      console.log("Error", err)
    } else {
      const itemCount = data.Count
      const response = {
        statusCode: 200,
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Credentials': true,
        },
        body: JSON.stringify({
          itemCount: itemCount,
          assets: data
        }),
      }
      callback(null, response);
    }
  })
}

// get one asset doesn't work:
module.exports.getAsset = function(event, context, callback) {
  const params = {
    TableName : 'Assets',
    Key: {
      AssetId: event.pathParameters.assetId // also tried to just hardcode it like this: 'ID-1178' 
    }
  }

  const request = documentClient.get(params, function(err, data) {
    if (err) {
      console.log("Error", err)
    } else {
      const response = {
        statusCode: 200,
        headers: {
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Credentials': true,
        },
        body: JSON.stringify({
          asset: data
        }),
      }
      callback(null, response);
    }
  })

Although it's a CORS error, as you can see the origin headers are provided, and I found that in combination with the 502 status it might be something before the CORS, e.g. a problem in the function or with authorization. However, I can't see any problems with them so far.

The serverless function itself works as well when invoke it locally: npm run sls -- invoke local --function getAsset -p test.json

Do you have any ideas what could be the issue or how to debug it?

Upvotes: 1

Views: 1608

Answers (1)

LostJon
LostJon

Reputation: 2387

Your issue may be as simple as having dynamodb:GetItem. This is a different permission than what listing all (ie query or scan) would be

Upvotes: 1

Related Questions