CORs error when accessing Square V2 API - laravel

I'm making a client-side request out to V2 of the Square API using Vue and Axios. My Vue component is as follows:
import axios from 'axios';
export default {
mounted() {
var instance = axios.create({
baseURL: 'https://connect.squareup.com/v2/',
timeout: 1000,
headers: {
'Authorization': 'Bearer xxxxxxxxxxxxxxxxx',
'Accepts': 'application/json',
'Content-Type': 'application/json'
}
});
instance.get('catalog/list')
.then(function (response) {
console.log(response);
}) ;
}
}
However, when I make that call, I receive the following error:
Failed to load https://connect.squareup.com/v2/catalog/list: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://local-env.dev' is therefore not allowed access. The response had HTTP status code 403.
That error suggests that there is some configuration that has to happen on the Square side, but I saw no opportunity to whitelist domains, etc.
Has anyone come across this error before, regardless of service, and if so, how did you resolve?

I don't think the Square API supports being called from a browser. I used Postman to do an OPTIONS request on https://connect.squareup.com/v2/catalog/list and the response was a NOT_FOUND. The OPTIONS request is needed for proper CORS support.
Plus, if you did this, I would think your auth token would need to be sent to the client -- thus exposing it to everyone. It looks like the Square API is only designed to be called from a server. But that is just based on me skimming the docs a bit. I have no experience using their API.

When doing OAuth authorization request you are not supposed to do it from your application. Create and URL with the parameters and open it in a new browser window or tab, Something like:
const grants='MERCHANT_PROFILE_READ CUSTOMERS_READ CUSTOMERS_WRITE PAYMENTS_READ PAYMENTS_WRITE PAYMENTS_WRITE_ADDITIONAL_RECIPIENTS PAYMENTS_WRITE_IN_PERSON';
const params = new HttpParams()
.set('scope', grants)
.set('client_id', <YourSquareApplicationId>)
.set('state', '1878789');
const requestUrl = `${<squareUrl>}/oauth2/authorize?${params.toString()}`;
window.open(requestUrl, "_blank");
That new window is supposed to ask the end user to login to his account and accept or deny the request.

Related

How to integrate AWS API Gateway API Key with Axios | CORS Error

I have built an API in AWS API Gateway. I have written the endpoints to perform basic CRUD operations as well. I am making a call to those endpoints using axios from my React frontend. The APIs in turn call AWS Lambda functions to interact with DynamoDB.
Since DynamoDB contains sensitive user data, I wish to secure it with an API key.
As per the steps mentioned here and here.
Now in order to make an API call I had the following code. Please note that I have swapped in the real values with dummy values for explanation purposes.
src/config/api.js
const customHeaders = {
"X-Api-Key": "thisIsADummyStringForExplanation",
"Content-Type": "application/json",
};
const axiosInstance = axios.create({
baseURL: "https://this.is.a.dummy.base.url/v0",
headers: customHeaders,
});
const Aws_Api_Gateway_GET = (uri) => {
return axiosInstance({
method: "get",
url: `${uri}`,
timeout: 2000,
});
};
export { Aws_Api_Gateway_GET };
Following is the Code that I wrote in order to make a GET request at the API endpoint
Aws_Api_Gateway_GET("/my-resource")
.then((res) => {
console.log(res);
})
.catch((err) => {
console.error(err);
});
THE ISSUE
This code throws CORS Error. I can assure that I have enabled CORS on the API Gateway by selecting the Enable CORS option for each and every resource.
Following is the error
Access to XMLHttpRequest at 'https://this.is.a.dummy.base.url/v0/my-resource' 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.
But when I try the same using Postman, it works.
Can someone please help me get rid of the CORS Error ?
Thanks in advance.

I'm getting "blocked by CORS policy" when I try to call Instagram API using Axios [duplicate]

This question already has answers here:
Access-Control-Allow-Origin with instagram api
(1 answer)
CORS error, when i use instagram API with angularjs
(1 answer)
Closed 3 years ago.
I'm trying to fetch some images from my Instagram account in a Laravel application with Vue as front end. When I try to do it in a standalone Vue app, it works well, but when I do so with Laravel, I got a message saying "has been blocked by CORS policy: Request header field x-csrf-token is not allowed by Access-Control-Allow-Headers in preflight response."
I'm using Laravel 5.8 and the Vue and Axios that comes within in and I'm using Homestead as my localhost server.
I've tried a lot of tips that I found here and on Google but I had no success. Basically, I'm trying the very basic of Axios call
beforeMount() {
axios.get('https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]').then(response => console.log(response))
}
I already created a Cors middleware on Laravel and tried a lot of headers settings on Axios.
I'm basically trying to retrieve a list of my Instagram posts and bypass that cors / x-csrf error.
Laravel automatically applies the X-CSRF-TOKEN header to all axios requests. This is so you can communicate with your application without having to pass the CSRF token every time for POST, PUT, DELETE, etc.
resources/js/bootstrap.js (default settings)
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just
* a simple convenience so we don't have to attach every token manually.
*/
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
You should be able to remove the offending header by doing something like this:
beforeMount() {
// create a new instance so we don't delete the csrf token for other requests
let instance = axios.create();
// delete the x-csrf-token header
delete instance.defaults.headers.common['X-CSRF-TOKEN'];
// use the new instance to make your get request
instance.get('https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]')
.then(response => console.log(response))
}
Your AJAX request to the Instagram API endpoint has to be sent as a jsonp request which means the dataType of the request has to be jsonp.
This blob in axios repository contains an example of sending a request using jsonp which is mentioned below.
Install jsonp package, if you haven't already.
npm install jsonp --save
and then;
const jsonp = require('jsonp');
jsonp('http://www.example.com/foo', null, (err, data) => {
if (err) {
console.error(err.message);
} else {
console.log(data);
}
});
Below is an example of sending a request using jQuery method with jsonp dataType to the Instagram API endpoint.
$.ajax({
url: "https://api.instagram.com/v1/users/self/media/recent/?access_token=[MY_ACCESS_TOKEN]",
type: "GET",
crossDomain: true,
dataType: "jsonp",
success: function(response){
console.log(response);
}
});

Apollo Client: Send different headers relative to authentication/authorization

I will often have an expired authorization token in my app.
I do not, however, want this error to block requests that do not require authorization. What is the work around?
I'd like to customize my headers for requests to simply view a page (which doesn't require token, so send with an empty header) and for requests to edit data (add token and allow error to block request).
An invalid token, with headers set like below for every request, is now blocking the simple fetching of open data:
const client = new ApolloClient({
uri: "http://localhost:8000/graphql",
request: operation => {
const token = sessionStorage.getItem('jwtToken');
operation.setContext({
headers: {
'x-token': token || '',
},
});
},
});

Nuxtjs Axios in Vuex Module CORS error

I am using Nuxtjs and built-in Vuex modules along with Nuxtjs's official axios. I'm trying to GET from my local server and it always throw CORS error.
So I made an API call to Github's public endpoint, and unsuccessfully only getting CORS error in my console.
I'm using Store actions to launch AJAX calls to server on component create lifecycle. Here is my code.
// component.vue
created () {
this.$store.dispatch('getGithubAPI')
}
// store action
async getGithubAPI ({ commit, state }) {
await this.$axios.$get('https://api.github.com/users/kaungmyatlwin', { headers: { 'Access-Control-Allow-Origin': '*' } })
.then(resp => {
console.log(resp.data)
})
}
Still no luck of getting it. Here is an error message that was thrown to console.
Failed to load https://api.github.com/users/kaungmyatlwin: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://localhost:3000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
What did I do wrong here? Or is it an error residing in async/await?
UPDATE: Strange thing is that the network call actually goes out and fetch data from server, as it can be seen in Network console from Chrome.
Ok I seem to have figured out this problem.
In nuxt.config.js, you have to put credentials: false to allow CORS wildcard.
My axios config here.
axios: {
baseURL: 'https://api.github.com',
proxyHeaders: false,
credentials: false
}
Reference: https://github.com/nuxt-community/axios-module#credentials

Ionic 2 ASP APi token request

I'm Trying to retrieve a bearer token from my ASP API from my ionic2 app.
I have enabled CORS on the API as shown below:
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
This enabled me to form a POST request from my ionic 2 app to my API in order to register a user. This works wonderfully.
The request I used for this is as shown below:
let headers = new Headers({
'Content-Type': 'application/json'
});
let options = new RequestOptions({
headers: headers
});
let body = JSON.stringify({
Email: credentials.email,
Password: credentials.password,
ConfirmPassword: credentials.confirmPassword
});
return this.http.post('http://localhost:34417/api/Account/Register', body, options)
However when I try to retrieve a token from my API I receive the following error:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.
The request I'm using to try and retrieve the token is as follows:
let body = "grant_type=password" + "&userName=" + credentials.email + "&password=" + credentials.password;
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
return this.http.post('http://localhost:34417/token', body, options)
This is the only request that is throwing this error, all other requests to my API work fine.
Have I missed anything, or am I doing something wrong?
var cors = new EnableCorsAttribute("*", "*", "*");
Looks like you are setting Access-Control-Allow-Origin as *.
Check MDN CORS Requests with credentials.
Credentialed requests and wildcards
When responding to a credentialed request, the server must specify an
origin in the value of the Access-Control-Allow-Origin header, instead
of specifying the "*" wildcard.
You will have to set a specific url if you use credentials.
Or if you only intend to use only for ionic 2, you could avoid the cors issue by setting a proxy.
According to the official blog:
The proxies settings contain two things: the path you use to access them on your local Ionic server, and the proxyUrl you’d ultimately like to reach from the API call.
{
"name": "ionic-2-app",
"app_id": "my_id",
"proxies": [
{
"path": "/api",
"proxyUrl": "http://localhost:34417/api"
}
]
}
Ionic serve command by default will start server on localhost:8100.
The set proxy will hit your http://localhost:34417/api.
Your path in the requests will be to the localhost:8100/api instead of your actual server.

Resources