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

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?

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.

Related

CORS policy error with AWS API Gateway in React

I am trying to set up an API Gateway to call another lambda function that will upload an image to S3. The feature works well when I am using an app like POSTMAN, however when I run the browser using React I am getting the following error.
Access to fetch at 'https://.../upload' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.
In my API Gateway I have the following configuration for that method
Gateway Responses for UserUpload API: default 4XX (not checked), default 5XX (not checked)
Methods: post (checked), options (checked)
Access-Control-Allow-Methods: options, post
Access-Control-Allow-Headers: '*'
Access-Control-Allow-Origin: '*'
This API uses an authorizer, I am using the one provided by Auth0 and have not edited the code at all.
And the function that my authorizer calls returns the response like the below (eg happy path):
exports.handler = async (event) => {
//do data checks and upload to s3
return {
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Origin": "*",
},
statusCode: 200,
body: JSON.stringify({ message: "success" }),
};
This is my first time setting up both a lambda function, authorisation provider and API Gateway so I might be missing something obvious. I have also tried added mode: no-cors to my fetch POST requests however they still fail in a very similar way.
From what I can tell by looking at the logs of the authorizer and the lambda function that uploads the images, is that they are not even being called. So it appears the CORS error is with the API Gateway.
I have seen in a few tutorials that in their aws template yaml files they add an option AddDefaultAuthorizerToCorsPreflight as False. I can't see this anywhere in the API Gateway console.
Update: I have tested my function with the custom authoriser turned off and it works. So I know that CORS works for the options method, and for the returned request on the lambda function. It is the custom authoriser that is the problem.
The flow is currently:
Method Request - Auth: my-auth-0-authorizer
Integration Request - Type: Lambda_proxy
Lambda function
Integration response - [greyed out Proxy integrations cannot be configured to transform responses]
Method Response: HTTP Status: Proxy (with Access-Control-Allow-Origin in the response headers)
What do I have to do differently or change to allow my authoriser to respect the CORS config?
Update: After leaving my API Gateway for a day, successful responses are now working (using the flow mentioned above). I am not sure if there was a glitch in the system or there was unexpected occurring but it is now working. I am still getting a CORS issue but now only with bad responses.
The custom authoriser fails by return context.fail("Unauthorized"); and when this occurs my browser gets a CORS error. Do I have to set up special gateway responses for 4XX responses?

API Gateway: Can't Enable CORS

I can't Enable CORS on my API Gateway instance, this is how it looks:
1. Settings:
2. Result:
I've tried a bunch of things like checking the DEFAULT 4XX and DEFAULT 5XX and manually inputting the Access-Control-Allow-Methods as suggested in some posts.
If I hover over the error I get: Invalid Response status code specified.
I'm able to GET using my browser but POST can only be done from Postman. My ReactJS website won't post either, throwing:
Access to XMLHttpRequest at <ENDPOINT> from origin <S3-REACT-BUCKET> has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I've read that I have my React app should send the CORS headers (haven't got to that) but I can't even Enable CORS in the API Gateway!
That was because No Method Response
You shouldn't manually go on the console to enable CORS. Instead follow this guide from the serverless framework.
In short:
set cors: true in your http event
return {'Access-Control-Allow-Origin': '*','Access-Control-Allow-Credentials': true} in your handler

Spring Security Oauth2 Swagger

I am attempting to configure Swagger Authentication on my resource server, so that I can authenticate against my authorization server.
I have the resource and authorization servers separated. They are both starting up on my localhost with different ports.
Resource Server on port 8083
Authorization Server on port 8081
Whenever I attempt to "Authorize", there is a CORS issues.
I forked a project from another website to use as my testing grounds. Below is the forked project.
https://github.com/cbriarnold/oauth2-spring-boot-2.0.2
To test, once both the authorization server and resource server are started, do the following:
Go to http://localhost:8083/swagger-ui.html
Click on "Authorize" button
Click on "Authorize" button in dialog
If you have the developer tools open, you will see that there is the CORS error
Access to fetch at 'http://localhost:8081/oauth/token/' from origin 'http://localhost:8083' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.
The http status code associated with the above CORS error was 302.
So, I modify the source to try to permitAll (I know this is undesired from a security perspective, but I am just trying to figure out what is going on). I will receive the same CORS error, but with the https status code of 403. Code is found on the following branch.
https://github.com/cbriarnold/oauth2-spring-boot-2.0.2/tree/permitAll
Any suggestions?
I think you need to add #CrossOrigin(/*your hitting server*/) on your controllers
it's a chrome security check to see if your are permitted to talk with that server or not it sends an option request at first and if you're permitted it send your original request which is accessing swagger
if you want to make sure if that is a cross origin problem or not try to send that request via postman because postman send your request direct without option request at first

POST request to AWS API Gateway access

I have a AWS Lambda function that is triggered via AWS API Gateway. When I test my function on Lambda it is working. When I send a POST request to the API url via ajax, I get a 502 bad gateway error.
XMLHttpRequest cannot load https://xxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/myLambdaFunction. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'mywebsite.com' is therefore not allowed access. The response had HTTP status code 502.
Obviously this was a CORS issue, so I thought I could change the CORS settings in my AWS API Gateway URL which I did, but I am still getting an error for this.
What do I have to change on AWS side or my own to be able to POST to the URL?
Unfortunately there is a known issue with many classes of 4xx and 5xx errors where CORS headers will not be sent, even if you've added CORS support via the console.
As noted in comments, the CORS error is a side effect of the fact that your API is returning a 502. This often occurs if you are using the LAMBDA_PROXY integration type and are returning invalid JSON from your Lambda function.
Please try either using the test invoke functionality from the console or enable logging in your API to debug further.
I solved that exact same problem by outputting the CORS header myself.
See below - and I hope that'll help.
Teebo
Amazon docs
function respond(context, responseData) {
var response = {
statusCode: 200,
body: JSON.stringify(responseData),
headers: {
"Content-Type": "application/json; charset=utf-8",
"Access-Control-Allow-Origin": "*"
}
};
context.succeed(response); }

On Developing Mobile app using ionic and web api 2.0

web api is hosted on secure server and i am accessing it through a path locally it is working fine. but after hosting an api
I am Getting this error while running an application
XMLHttpRequest cannot load https://xxxxx.xxxxapp.net/xxx_API/token. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access. The response had HTTP status code 400.
Well, your error give you an info about what to do. You are doing request with CORS (Cross-Origin Resource Sharing). It says that your request does not have Access-Control-Allow-Origin request header specified. So you should provide it. More about CORS
try to put this in your ionic.project file
"proxies": [
{
"path": "/api",
"proxyUrl": "https://xxxxx.xxxxapp.net/xxx_API/token"
}
]
}
and change the proxuUrl with your api path

Resources