API gateway axios network Error on Mac OS - amazon-web-services

I am trying to call an API with axios from my ReactJS application (Mac). But I keep getting this error message,
Access to XMLHttpRequest at 'https://api_url/' from origin 'https://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.
I referred other stackoverflow answers but the error is still coming. I don't know where I made a mistake whether It is in AWS backend or Frontend. If anyone has an idea or solution please share.
Thanks in advance,

This is due to Cross Origin Resource Sharing (CORS) being disabled by default.
Your React app comes from a different domain (e.g https://localhost:3000) and therefore cannot call remote servers by default (e.g 'https://api_url/).
See Wikipedia and enable-cors for great explanations.
This must be enabled explicitly.
AWS API Gateway will let you do this from the UI.
Select your API in the UI
In the actions dropdown choose "Enable CORS"
Follow the forms to enable and you should be good to go!

Related

Setting up OIDC for a backend API + frontend SPA

I’ve got a project using a Django backend, with Django Rest Framework to serve an API, and a Vue.js frontend SPA to consume the API. I’m running into some kind of CORS issue during authentication.
I’ve been using mozilla-django-oidc to implement the Authorization Code flow with Okta. This works fine pretty much out of the box, and if I navigate to the API in my browser, I can login to Okta and I get a Django session. I’ve also enabled SessionAuthentication for DRF, which allows the same session cookies generated by Django to be accessible by the SPA (both SPA and API are on the same domain), provided I login first directly through the API. This all works fine until the id token expires. In Django, when the id token expires, I get a redirect to https://example.okta.com/oauth2/v1/authorize?..., the Authorization Code flow completes and I get sent on through to the originally requested page. Where things fail is in an ajax request from the SPA to the API with an expired id token. I get the same redirect, but this time it fails due to CORS.
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=code&client_id=X&redirect_uri=http%3A%2F%2F127.0.0.1%3A8000%2Foidc%2Fcallback%2F&state=X&scope=openid+email+profile&prompt=none&nonce=X' (redirected from 'http://127.0.0.1:8080/api/X') from origin 'http://127.0.0.1:8080' 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.
I’ve tried to identify why it’s failing.
On local development, I’m running my API on 127.0.0.1:8000 and my SPA on 127.0.0.1:8080, so clearly the origins don’t match. I have Vue setup with a proxy so it looks like requests are coming from 8080, but the redirect_uri in the request to Okta is still using 8000.
When I deploy to a test server, I’m using docker containers for the API and SPA and a reverse proxy to route requests and also for SSL. In this case, the API and SPA have the same origin (I think). Yet I still get the same error message.
Access to XMLHttpRequest at 'https://example.okta.com/oauth2/v1/authorize?response_type=code&client_id=X&redirect_uri=http%3A%2F%2Fexample.com%2Foidc%2Fcallback%2F&state=X&scope=openid+email+profile&prompt=none&nonce=X' (redirected from 'https://example.com/api/X') from origin 'https://example.com' 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 you notice, the redirect_uri is http, not https. I suspect that is why this is failing. Though I’m not entirely confident because if I navigate my browser to the API, I am on https, but the redirect_uri is still http, and it still successfully authenticates.
Any insight would be really helpful.
What am I doing wrong or missing here?
Am I approaching the authentication flow all wrong for an API+SPA app? Should I do authentication on the SPA instead? How does the API then know who’s logged in?
Edit: I have already tried adding the origins to the Security > API > Trusted Origins section in Okta configuration. No dice.
https://developer.okta.com/docs/guides/enable-cors/overview/
In Okta, CORS allows JavaScript hosted on your websites to make a request using XMLHttpRequest to the Okta API with the Okta session cookie. Every website origin must be explicitly permitted as a Trusted Origin.
So configure your Trusted Origins properly in the Okta client configuration.
Are you making an AJAX call to /authorize ? That could be the reason for the error.
As mentioned here, when making requests to the /authorize endpoint, the browser (user agent) should be redirected to the endpoint. You can't use AJAX with this endpoint.

Handling "Missing Authentication Token" after setting up AWS Lambda with API Gateway

Here are the exact steps I just followed to setup a Lambda function behind and API Gateway.
1. Select blueprint
2. Add trigger
3. Configure
4. Create Role
5. Create Function
6. Congrats
7. Deploy API
However, when I visit the endpoint:
https://hq1hf4tmlf.execute-api.us-west-2.amazonaws.com/prod/myLambda
I get the following error:
{
"message": "Missing Authentication Token"
}
The error you are getting is because the API key isn't included when you invoke the API through the URL alone.
With the way you currently have it set up, you would need to use something like python's requests package to call the API and invoke the lambda:
import requests
CustomHeader = {'x-api-key': YOUR_API_KEY}
Response = requests.get(YOUR_API_URL, headers=CustomHeader)
Or, you could go back into your API's configuration (under Your API/Resources/API Call/Method Request) and disable use of your API key for that call, but is a very insecure option.
You may want to check if you have a web security service or web filtering proxy installed on your device that might be stripping off JWT/auth tokens from requests going out of your work/home network. I had the same problem where I was getting “Missing Authentication token” error while trying to create a lambda function on my work laptop. After struggling for few hours, I switched on to my personal laptop and was able to create the lambda function successfully in the first attempt. I then tried again on my work laptop with fiddler turned on and noticed that even though the auth credentials were setup properly in my outbound request, I was still getting “x-amzn-ErrorType: MissingAuthenticationTokenException” from AWS in the response. I turned off the web security proxy service on my work laptop and I was able to create Lambda functions successfully. Hope it helps.

OPTION request rejected by CloudFront

Since last week I have been struggling to fix this problem but still its not resolved. I have deployed my Django code on AWS lambda and configure the API gateway to serve all api and admin section.
All http method are working fine from rest client/postman but when I am trying to integrating the api in AngularJS then try to perform the POST request to the api but Chrome sends a default OPTION request to the server but every time CloudFront returns an error with 500 status.
"Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource."
Please help me to resolve the issue as I need to move my product to production.
Thanks,
AbdulWahid
Thanks to Michael-sqlbot's comment, I finally succeed to get 200 response from AWS Lambda. Just enable CORS for your Method in API Gateway then it will work.

Missing Authentication Token while accessing API Gateway?

I am trying to call a Lambda Function through AWS API Gateway.
When I mention Authentication type NONE it works fine but API become public and anyone with url can access my API.
To make API call secure, I am using Authentication type AWS_IAM and
also attached AmazonAPIGatewayInvokeFullAccess policy to my user but getting this error:
{ message: "Missing Authentication Token"}
I don't know what I am missing here.
I've lost some time for a silly reason:
When you create a stage, the link displayed does not contain the resource part of the URL:
API URL:
https://1111.execute-api.us-east-1.amazonaws.com/dev
API + RESOURCE URL
https://1111.execute-api.us-east-1.amazonaws.com/dev/get-list
The /get-list was missing
And of course, you need to check that the method configuration looks like this:
I think you are directly trying to access API link, this won't work because API is secured using IAM role and you must provide AWS authentication i.e Access key and Secret key.
Use the Postman Chrome extension to test your API:
http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html
I just had the same issue and it seems it also shows this message if the resource cannot be found.
In my case I had updated the API, but forgotten to redeploy. The issue was resolved after deploying the updated API to my stage.
Make sure you are clicking on the specific Resource first in the Stages tree, as that will populate a URL with the full path to the resource (rather than just the root path):
For other causes, see http://www.awslessons.com/2017/aws-api-gateway-missing-authentication-token/
Looks like (as of April 2019) AWS API Gateway throws this exception for a variety of reasons - mostly when you are hitting an endpoint that API Gateway is not able to reach, either because it is not deployed, or also in cases where that particular HTTP method is not supported.
I wish the gateway sends more appropriate error codes like HTTP 405 Method not supported or HTTP 404 not found, instead of a generic HTTP 403 Forbidden.
Found this in the docs:
If the AWS_IAM authorization were used, you would sign the request using the Signature Version 4 protocols.
Signing request with Signature Version 4
You can also generate an SDK for your API.
How to generate an SDK for an API in API Gateway
Once you've generated the SDK for the platform of your choice, step 6 mentions that if you're using AWS credentials, the request to the API will be signed:
To initialize the API Gateway-generated SDK with AWS credentials, use code similar to the following. If you use AWS credentials, all requests to the API will be signed. This means you must set the appropriate CORS Accept headers for each request:
var apigClient = apigClientFactory.newClient({
accessKey: 'ACCESS_KEY',
secretKey: 'SECRET_KEY',
});
I try all the above, if you did all steps in the above answers, and you not solve the problem, then:
on the left menu, hit the "Resources"
in the right to "Resources", hit the api method that you want to test, like "POST/GET etc)
hit the "ACTION" list (it's above to the API method in step 2
select "DEPLOY API" (please do it, even you already deploy yours api)
in "deployment stage" select "prod" or what ever you write in yours previous deploy (it will override yours previous deploy
hit deploy
I thing that because of, when I create the "METHOD REQUEST" (see step 2 how to go to this menu) , in "Authorization" I select "AWS_IAM"
after testing api, in aws test option, I try it in "postman"
then I understand the in "METHOD REQUEST" , in "Authorization", I should select "none"
I change it to none, but I thing the AWS, need to deploy it again, as I explain
Make sure you create Resource and then create method inside it. That was the issue for me. Thanks
In my case I missed adding '/' forward slash at the end of api.
Such a silly mistake.
https://le9dq5l9.execute-api.eu-west-1.amazonaws.com/v1/putdoctorinfo/
If you enable AWS_IAM authentication you must sign your request with AWS credentials using AWS Signature Version 4.
Note: signing into the AWS console does not automatically sign your browser's requests to your API.
sometimes this message shown when you are calling a wrong api
check your api endpoint
In my case it was quite a stupid thing.
I've get used that new entities are created using POST and it was failing with "Missing Authentication Token". I've missed that for some reason it was defined as PUT which is working fine.
This error mostly come when you call wrong api end point.
Check your api end point that you are calling and verify this on api gateway.
If you are using an API with endpoint of type PRIVATE, be sure of:
You are invoking the API from within your AWS account (example: from an EC2 instance created in your account)
Put necessary credential (access and secret keys) in the EC2 instance in route ~/.aws/credentials (this route is for linux instances) If IAM user use MFA aws_session_token value will be required too.
Use vpce (vpc endpoint) based URL. Example: curl https://vpce-0c0471b7test-jkznizi5.execute-api.us-east-1.vpce.amazonaws.com/dev/api/v1/status
Your EC2 instance have a security group than allow outbound traffic to another security group owned by the vpce like:
Your vpce security group allow inbound traffic from another security group (previous sg from ec2 instance) owned by the EC2 instance like:
See: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-apis.html
I had the same problem which I solved the following way:
GET Method test
https://54wtstq8d2.execute-api.ap-southeast-2.amazonaws.com/dev/echo/hello
Authorization tab ->
• select type(AWS signature)
• Add AccessKey and SecretKey
You must be using Invoke Url to trigger Lambda Function from your browser or POSTMAN... Instead, use the API end point which will be listed in:
select yourLambdaFuntion >> Configuration >> Triggers.
There you can see API end point.
For the record, if you wouldn't be using credentials, this error also shows when you are setting the request validator in your POST/PUT method to "validate body, query string parameters and HEADERS", or the other option "validate query string parameters and HEADERS"....in that case it will look for the credentials on the header and reject the request. To sum it up, if you don't intend to send credentials and want to keep it open you should not set that option in request validator(set it to either NONE or to validate body)
I had the same issue, and fixed it by removing the /dev/ and just put: https://1111.execute-api.us-east-1.amazonaws.com/get-list
I had same issue today because I was using GET instead of POST. Fixed the issues by changing method to POST in postman.
First of all, check whether the API you created in the lamda function is registered with your AWS project or not. For that, go to the API gateway in your AWS console. If it is not registered, register it. This is the main cause of this issue.
You can even see in your aws.export.js file, that there are paths corresponding to your API ['/items'].
Your API must be present there, otherwise it will not append the security token to requests. Just register it in your project cloud-logic in your console for this.
If it's there, then use the above mentioned solution
http://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-use-postman-to-call-api.html
To contribute:
I had a similar error because my return response did not contain the 'body' like this:
return {
'statusCode': 200,
'body': "must contain the body tag if you replace it won't work"
}
If you set up an IAM role for your server that has the AmazonAPIGatewayInvokeFullAccess permission, you still need to pass headers on each request. You can do this in python with the aws-requests-auth library like so:
import requests
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
auth = BotoAWSRequestsAuth(
aws_host="API_ID.execute-api.us-east-1.amazonaws.com",
aws_region="us-east-1",
aws_service="execute-api"
)
response = requests.get("https://API_ID.execute-api.us-east-1.amazonaws.com/STAGE/RESOURCE", auth=auth)
Well for anyone still having the problem and I really feel very dumb after realizing this, but I passed in the url of /items the default one while adding API. But I kept calling the endpoint with /api. Special thanks to Carlos Alberto Schneider, as I realized my problem after reading your post.
According to my experience, please check the following steps:
On API gateway side, make sure you add the correct path and publish the resource at the stage you want. For some url pattern like path parameter(/user/{user_id}) need more attention to have a check.
Make sure you configure the correct options method for this resource, because sometimes it is the CORS that cause this problem.
On Lambda side, make sure you specify the correct handler name as the entrypoint.
Please always check cloudwatch logs of your lambda that can help u identify the problems on your lambda side.
In my case I was trying to do an UPDATE type request but in my AWS SAM template I had a PATCH type request:
Resources:
LambdaFunction:
Type: AWS::Serverless::Function # More info about Function Resource:
# https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: src/
Handler: app.lambda_handler
Runtime: python3.8
MemorySize: 128
Events:
UpdateItem:
Type: Api
Properties:
Path: /my-endpoint
Method: patch
Things to check:
1. In resources, check for Authorization and API Key if these are required.
2. Redeploy the API, new changes might not reflected.
3. Get the url from stages, directly by clicking on the actions like GET, POST, These will contain the full path urls.
I had the same issue even if my access was regional and not private, no authorization on my method neither API. It's turned out that I was calling the root endpoint "https://azerty.execute-api.eu-west-3.amazonaws.com/dev/", which in local return me a json but raised an error. Be sure to call a proper endpoint, such as "https://azerty.execute-api.eu-west-3.amazonaws.com/dev/hello"

WSO2 APi Manager Response Code 0

I'm trying to use WSO2 API Manager 1.10.0 on an existent micro-services project with REST APIs following WSO2 tutorial.
I have installed it on my computer as well as a copy of my application and configured AM to manage requests (GET, POST and DELETE) to my resource but I always obtain a "Response code 0" with Response Header
{
"error": "no response from server"
}
Trying to contact my application using Advanced REST Client I obtain 200 with the correct result.
My APIs use a token inside the header to authenticate the user passed so I have implemented a dummy API without authentication but I still have the same issue.
I have tried also the Cloud version with our test server but still obtaining the same result.
I found this guide http://wso2.com/blogs/cloud/video-setting-up-custom-url-for-api-store-and-gateway/ but I don't know if this can be a solution for the problem in localhost.
Setting up the custom url in WSO2 API Cloud wont help. Thats there for a different purpose. There are two things you can do.
If you are interested in going ahead with the cloud version, you can get help from them. You can send a support request and the cloud team will help.
You can troubleshoot your local instance. When doing so, first, try to invoke your api via curl and see whether it gets a response. Sometime, your api can work fine, but due to some reasons, the result might not reach the api console.
If the curl works fine or not, you can check the logs to see whether there are any errors printed. Some more questions:
Is your backend service exposed via http or https?
If it is https, then if its certificate is not a CA signed one, API Manager will fail during the handshake. If so, you will have to add the cert to api managers client-truststore.jks
In the cloud scenario, your backend should be accessible from internet and the certificate story is valid for cloud too.
Are you trying to access the api using swagger console (or any web application). There are couple of reasons you could encounter this issue. one could be certificate not installed in the browser.
If this happens you should see some error log in the api manager console (something related to CA not found). for that first you can copy the backend url (swagger console shows the url it used to send the request) and paste it on a new browser window and install the certificate to the browser.
also you can get an idea about the issue by using a tool like firebug and check the request. (it will show the error for not connecting the AM)
Finally I have found the issue: the API Manager does not accept plain text response, responding using a JSON solves the problem.
Using other mediatype such as XML or TEXT/HTML it reports 406, with text plain it returns Error 0.