Laravel - Vue Axios CORS policy - laravel

The request
axios.get("https://maps.googleapis.com/maps/api/geocode/json?latlng="+this.currentLocation.lat+","+this.currentLocation.lng+"&key="+this.apiKey).then((response) => {
if (this.town === response.data.results[0].address_components[2].long_name){
return
}
else{
this.town = response.data.results[0].address_components[2].long_name
this.getSuggested();
this.getAllEvents();
}
}).catch(er => {
console.log(er)
})
When i'm trying to get the town of a location i get this error
Access to XMLHttpRequest at 'API Route' from origin 'http://localhost:8000' has been blocked by CORS policy: Request header field x-requested-with is not allowed by Access-Control-Allow-Headers in preflight response.
When i remove
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
from bootstrap.js, the request works just fine.
What exactly is the problem here?

Any server you’re sending a request to will, usually by default, reject it if it contains headers which are not CORS-safelisted.
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
This code tells axios to attach a custom header to every request. Ergo, your request is being sent with a non safelisted header, which the server won’t permit, so you receive the error.
To permit the request, the server must be configured to allow the custom header.

Related

Blocked by CORS policy: No 'Access-Control-Allow-Origin'. How to fix

I'm trying to hit an API from the browser using a AJAX call, and I see this inside my browser.
Access to XMLHttpRequest at 'https://.......us-east-1.amazonaws.com/...' from origin 'https://....cloudfront.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
The back-end was an actually a AWS lambda. So should I fix this on the client side or the server side?
Set headers to your LAMBDA response.
var response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers" : "*",
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify(data)
};
You can set Access-Control-Allow-Headers specific headers you want to allow instead of * (ALL) and domain also.

Stop sending preflight requests from axios.post

I have my micro-service developed using spring-boot and spring security and frontend is designed on react-hooks.
Now, while I am send some data to my micro-service using axios.post method, it send CORS preflight method i.e. options method because axios by default send content-type as application/json and application.json leads to send options request to server before any other request.
I have tried sending my request with different headers and content types as 'application/x-www-form-urlencoded' also I have used #cross-origin(*) at my server end.
const config = {
headers: {
'Content-Type': 'application/json'
}
}
const response = await axios.post(ps.user_ms_url+ps.user_login,
{
username:values.email,
password:values.password
// headers:{'tokenvalue':'token'}
},
config);
I expect my browser to send only post request to the server, for that I am ready to change my headers as well.
Any help will be appreciated. Thanks in advance!
I found the solution for my query. As I mentioned above, our browser sends preflight request (means options request) before any other request if our request is not simple (here simple means: if request contains content-type : application/json or custom headers etc) and if we are sending this request to some other domain/ URL.
And our axios.post method carries content-type as application/json by default, that's why, my browser was sending multiple requests (means preflight request before any other request).
Now, I have changed my request content-type to application/x-www-form-urlencoded by sending data as params, as shown below:
var params = new URLSearchParams();
params.append('username', values.email);
params.append('password', values.password);
const response = await axios.post(ps.user_ms_url+ps.user_login,
params);
And handling this request at backend using #ModelAttribute annotation (Spring-boot). So, keeping request simple can stop preflight requests.
You can avoid CORS preflight request by proxying the request. Add this in your webpack development config
devServer: {
port: process.env.PORT || 3000,
proxy: {
'/api': {
target: 'http:localhost:8080',
pathRewrite: { '^/api': '' },
changeOrigin: true,
},
},
}
This means your request to /api/users will forwarded to http://localhost:8080/users.
If you are using create-react-app. just add "proxy": "http://localhost:8080" to your package.json. Check more info here
This looks to be server side CORS issue. You have to allow domains to access resources by providing correct response headers.
You can look at adding CORS headers in spring boot. Refer to this link
Hope that helps!!!

CORs error when accessing Square V2 API

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.

Axios not sending basic authorization

In a VueJS app I am making an axios call to an API on a remote server. The server is set up to return the correct CORS headers (Access-Control-Allow-Origin, and Access-Control-Allow-Headers). It looks like the auth headers are not sent at all.
Here is the pertinent code:
var config = "auth: {username: 'username', password: 'secret'},
headers: {accept: 'application/json'}";
axios.get(self.link, config)
.then(function (response) {
self.jobDetails = response.data;
console.log(response.data);
})
.catch(function (error) {
console.log(error);
});
The accept header is sent correctly. The auth header is not sent at all. So, I get a 401.
All searches for an answer point to CORS solutions. But, I do not get the CORS preflight error. So, I think the ORIGIN request is handled correctly.
Can anyone point me in the right direction?
TIA
EDIT
The Response header does include the Access-Control-Allow-Origin header. The server appears to be responding correctly.

Access-Control-Allow-Origin in preflight response doesn't enable cross-domain access

I am trying to send a CORS request using AJAX to a nodeJS server. I want to return some JSON data. I've found numerous tutorials online that all say the same thing, which I've tried, but I can't get this to work. Here's the AJAX request:
$.ajax({
url: "http://some.other.url.com:8880",
type: "GET",
crossDomain: true,
contentType: 'application/json'
}).then(function(response) {
$scope.allData = jQuery.parseJSON( response );
console.log($scope.allData);
}).fail(function(response) {
});
And here is the code on the server:
var path = url.parse(req.url).pathname,
match = router.match(path),
rescode;
console.log("---: " + req.method);
if (req.method === 'OPTIONS') {
var headers = {};
headers["Access-Control-Allow-Origin"] = "*";
headers["Access-Control-Allow-Methods"] = "POST, GET, PUT, DELETE, OPTIONS";
headers["Access-Control-Allow-Credentials"] = false;
headers["Access-Control-Max-Age"] = '86400'; // 24 hours
headers["Access-Control-Allow-Headers"] = "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
res.writeHead(200, headers);
return res.end();
}
I'v also tried it without the return on res.end() i.e. not returning the OPTIONS preflight request, and that doesn't work either.
--Edit--
Here is the actual error message in the console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://other.domain.com:8880/. This can be fixed by moving the resource to the same domain or enabling CORS.
The server is getting the requests. Both the OPTIONS and then GET requests are hitting the server and being responded to. In fact, in the console log for the page making the AJAX request, I can click on the CORS error and see the response, and it is the correct data. But I can't seem to get the javascript to continue.
In regards to .done vs .then, they seem to work interchangeable. Or at least, in this example, the .then and .fail are working just fine.
You're correctly setting CORS headers in your OPTIONS preflight response, but you also need to set Access-Control-Allow-Origin (either to your origin or *) on your actual GET response. The GET response should respond with the same CORS headers, regardless of whether there was a preflight response or not. This means that it must send the appropriate CORS headers, but it does not need to send anything except for Access-Control-Allow-Origin. (If other non-simple components like non-simple verbs or headers are involved, they will be allowed or denied in the preflight; the actual GET response does not need to worry about them.)
The Enable CORS site has a CORS testing tool to help you see the headers involved in a request that you specify. I've used that tool to set up a test similar to your case (GET with non-simple Content-Type header). If we examine the results of that test (careful -- the steps are presented little bit out of order, but they're all there), we see a preflight response:
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
...
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Access-Control-Allow-Headers: X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept
And the final CORS response:
Content-Length: 0
Content-Type: application/json
Access-Control-Allow-Origin: http://client.cors-api.appspot.com
Cache-Control: no-cache
As you can see, the GET response also has a Access-Control-Allow-Origin header and no other CORS headers. If you have any further uncertainties, feel free to tweak the settings on that tool to run a wide range of other test cases.

Resources