Reputation: 1291
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
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