Getting CORS Error when using Google Business API - google-api

I am using google business API and trying to get location list.
I am going trough their documentation and using project from the link below as basis
https://developers.google.com/my-business/content/implement-oauth
Using that project I am able to successfully retrieve accounts list.
The problem occures when I try to retrieve locations list using accountID. Here is a link for their documentation
https://developers.google.com/my-business/content/manage-locations
Acording to documentation, to get location list for specific account, I should use following request
GET
https://mybusinessbusinessinformation.googleapis.com/v1/{accountId}/locations
Authorization: Bearer <access_token>
This is the code snippet, that I added to their sample project
function retrieveGoogleMyBusinessLocations(accessToken) {
$.ajax({
type: 'GET',
url: 'https://mybusinessbusinessinformation.googleapis.com/v1/{accID}/locations',
headers: {
'Authorization' : 'Bearer ' + accessToken
},
success: function(returnedData) {
var e = document.createElement("pre")
e.innerHTML = JSON.stringify(returnedData, undefined, 2);
document.body.appendChild(e);
}
});
}
When I do this request, it gives "CORS error".
The error in the console is following
Access to XMLHttpRequest at 'https://mybusinessbusinessinformation.googleapis.com/v1/xxx/locations' from origin 'http://localhost:8001' 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.
GET https://mybusinessbusinessinformation.googleapis.com/v1/xxx/locations net::ERR_FAILED
From the error message it seems that server does no accept requests from localhost:8001, but if I do request to different endpoint it will return result.
For example if I change utl from
https://mybusinessbusinessinformation.googleapis.com/v1/{accID}/locations
to
https://mybusinessbusinessinformation.googleapis.com/v1/accounts/{accID}/locations?readMask=categories
With the second url it will return successfull result.
I am confused why it is allowing requests to one endpoint and blocks requests to other endpoint.
Can anyone help with this problem?

Have you tried making direct API requests via the Google Developers OAuth 2.0 Playground?
I tried to reproduce your error but got the expected 404 Not Found response for the unsupported endpoint pattern.

Related

Setting Up OAuth Authentication in SAP SuccessFactors

In order to get oData from success factors odata service, I'm trying to setting up a connection between SuccessFactors and SAP BTP by creating a destination as reported in this official guide.
Using postman everything works fine but, once I check the connection of destination previously created, the response received is 401: Unauthorized.
Below the configuration of destination:
Here you can see the properties:
And here the response:
I know that is wrong but, for the sake of curiosity, I've also created a different destination with no authentication. Then directly from code I've developed three nested ajax requests. First provides the assertion, second the user token, third is the one which, leveraging the token, get the odata. Sadly response is always 401: Unauthorized.
Below the code of last ajax request, the other two are good:
// Validate access token
$.ajax({
type: 'GET',
headers: {
"Authorization": "Bearer " + sAccessToken
},
url: '/oauth/validate',
success: function(data){
console.log("Success: ", data);
},
error: function(e){
console.log(e);
}
});
Here the request header:
So not sure how your flow really is. Normaly you would connect to BTP via a SAP Approuter which has a xs-app.json which defines the routes and destinations to use. Then the Approuter would Exchange the internal BTP JWT with a SAML Assertion for Successfactors. If you want to request the authentication infos for yourself via the BTP Destination Service, you have to send a valid BTP JWT to the destination service via the HTTP Header field X-user-token and as a response you would get back a Successfactors OAuth bearer token.
See here
hope it helps
Regards
Mathias

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?

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); }

identity Server - Configuring CORS for bearer options

I am testing the jquery ajax calls to the API server from a different domain. Unfortunately I am getting an OPTIONS error. Here is my request code:
$.ajax({
url: "https://localhost:44356/api/Default/",
headers: {
"Authorization": "Bearer " + user.access_token
},
success: function (res) {
logAjaxResult(res);
},
error: function() {
logAjaxResult('Error');
}
}))
Which gives
XMLHttpRequest cannot load https://localhost:44356/api/Default/. Response for preflight has invalid HTTP status code 405.
Normally this is an easy fix - I install Microsoft.AspNet.WebApi.Cors, set up a provider and allow OPTIONS through always. I can see how I would normally do this on the Identity Server box too as there is a CorsProvider you can register up. My issue however is on the API box I am using IdentityServerBearerTokenAuthenticationOptions and I see no CORs options. When I try to set up the WebAPI.cors provider though I get an error saying there are multiple origins set on the server to allow. This indicates to me (correct me if I'm wrong) that the WebApi box has somehow got the CORs settings from my identity server box that is registered as it's authority. Is this right?
How do I configure to allow pre-flight requests with app.UseIdentityServerBearerTokenAuthentication(options)?
Many thanks
This issue was resolved when I found the documentation uses
Microsoft.Owin.Cors
I was using the package
Microsoft.AspNet.WebApi.Cors

Clicking an href to our Github oAuth endpoint works, but an AJAX request to same endpoint gives a CORS error?

We are trying to implement Github oAuth in our app using Passport.js. If the user hits the endpoint by clicking an anchor tag/href, it works fine, but if we use a click handler to initiate an ajax request instead, we receive a CORS error from the Github server. Why?
Server side code:
app.get('/auth/github',
passport.authenticate('github', { scope: [ 'user:email' ] }));
app.get('/auth/github/callback',
passport.authenticate('github', { failureRedirect: '/login' }),
function(req, res) {
console.log('Github authentication successful!');
res.redirect('/');
});
Client side code (we are using React):
--> Works:
<a href='/auth/github'>Contact</a>;
--> Does Not Work - CORS error:
handleContactAuth(event) {
$.ajax({
url: '/auth/github',
method: 'GET',
success: data => console.log( 'Contact Auth response: ', data),
error: err => console.log( 'Error connecting to GitHub.', err)
});
}
NOTE: This is a click handler on the React component and is functioning fine, as the ajax request is being triggered. I'm aware we're not handling the response currently, apart from just a console.log.
--> CORS Error we see on the Client side when using AJAX method instead of href:
XMLHttpRequest cannot load https://github.com/login/oauth/authorize? response_type=code&redirect_uri=ht…auth%2Fgithub%2Fcallback&scope=user%3Aemail&client_id=our_client_code. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Any ideas? Would appreciate any insights - many thanks.
CORS error is not an error returned by the server, but one triggered by the browser if the response doesn't contain HTTP headers signaling that cross-origin requests are allowed. The endpoint you are hitting obviously isn't designed to be accessed like this.
I had the same problem and I found that at least in Google Chrome XMLHttpRequest object is restricted to same origin policy. So you may need to stick to using an anchor tag.
Regular web pages can use the XMLHttpRequest object to send and receive data from remote servers, but they're limited by the same origin policy. Extensions aren't so limited. An extension can talk to remote servers outside of its origin, as long as it first requests cross-origin permissions.
Link: https://developer.chrome.com/extensions/xhr

Resources