Search code examples
aws-lambdaaws-api-gatewayaws-amplifyapollo-server

blocked by CORS and also fail accessing REST API endpoint with Amplify Functions


I am following this link to deploy an Apollo GraphQL Server with Amplify Functions: https://dev.to/aws/10-minute-tutorial-deploy-an-apollo-graphql-server-with-amplify-functions-38p1

However, when I run "npm start", it fails to access 'http://localhost:3000', showing:

Access to fetch at 'https://******.execute-api.us-east-1.amazonaws.com/dev/graphql' 
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.
Failed to load resource: net::ERR_FAILED   
******.execute-api.us-east-1.amazonaws.com/dev/graphql:1 

Here is how I set exports handler in index.js for Lambda:

exports.handler = server.createHandler({
  cors: {
    origin: "*",
    credentials: true,   // I tried setting false is also the same
  },
});

I am not sure whether CORS is the root cause because I think the above config should make it work. I suspect that something going wrong for API end point. I see the failure using browser to access REST API endpoint, which is the link in aws-exports.js:

awsmobile.aws_cloud_logic_custom[0] = "******.execute-api.us-east-1.amazonaws.com/dev"

It shows:

{"message":"Missing Authentication Token"}

And I cannot access "******.execute-api.us-east-1.amazonaws.com/dev/graphql" either, showing:

{"message": "Internal server error"}

Is it because of missing AWS signature? Anything else I need to config for authentication?


Solution

  • Spent a few days, and found out the root cause. It is neither CORS nor authentication issue.

    According to https://docs.aws.amazon.com/apigateway/latest/developerguide/amazon-api-gateway-using-stage-variables.html, it is expected to see "Missing Authentication Token" because I shall access to child resource instead of the endpoint itself. The child resource here is "******.execute-api.us-east-1.amazonaws.com/dev/graphql".

    The Invoke URL link points to the root resource of the API in its beta stage. Navigating to the URL by choosing the link calls the beta stage GET method on the root resource. If methods are defined on child resources and not on the root resource itself, choosing the Invoke URL link returns a {"message":"Missing Authentication Token"} error response. In this case, you must append the name of a specific child resource to the Invoke URL link.

    For why it failed to access "******.execute-api.us-east-1.amazonaws.com/dev/graphql", I found that error by checking CloudWatch logs. It is a great tool for debug.

        "stack": [
            "Runtime.ImportModuleError: Error: Cannot find module 'apollo-server-lambda'",
    

    "amplify push" couldn't recognize this package because I used a terminal with node v6.9.5. After I update it to latest node and "amplify push", problem is solved.

    CORS error is a distract, it doesn't show up after the above issue is fixed. CORS header wouldn't be added because index.js failed to compile.