woocommerce rest api: can't get preflight request to pass - wordpress

I have a woocommerce site and I want its REST API to be open to the world.
I have learned that CORS headers need to be set, so I google and setup the following hook:
add_action('rest_api_init', function() {
remove_filter('rest_pre_serve_request', 'rest_send_cors_headers');
add_filter('rest_pre_serve_request', function( $value ) {
header( 'Access-Control-Allow-Origin: *' );
header( 'Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE' );
header( 'Access-Control-Allow-Credentials: true' );
header('Access-Control-Allow-Headers: Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Origin,Content-Type,X-Auth-Token,Content-Range,Range');
return $value;
});
}, 15);
I confirmed that my server is responding with the correct CORS headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers:
Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Origin,Content-Type,X-Auth-Token,Content-Range,Range
Access-Control-Allow-Methods: OPTIONS, GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-WP-Total, X-WP-TotalPages
Then I headed to code the client side:
xhr = new XMLHttpRequest();
xhr.open('POST', 'https://..../wp-json/wc/v3/products');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Authorization', 'Basic ' + btoa('mykey:mysecret'));
xhr.send(JSON.stirngify({ ... });
Above code was entered in Chrome console under a https://google.com tab. I just can't get the preflight request to work, here are the errors:
OPTIONS https://..../wp-json/wc/v3/products 401 (Unauthorized)
Access to XMLHttpRequest at 'https://..../wp-json/wc/v3/products' from origin
'https://www.google.com' has been blocked by CORS policy: Response to
preflight request doesn't pass access control check: It does not have
HTTP ok status.
Even though the response headers are exactly like posted above.
What am I doing wrong?

if you are using: "Access-Control-Allow-Credentials" = true make sure that "Access-Control-Allow-Origin" is not "*", it must be set with a proper domain!

Related

No 'Access-Control-Allow-Origin' header is present on the requested resource. on the Pantheon Site

I have created a Webservice in Drupal 9 of the Pantheon (Locked) Site that I need to call from another domain. I have tried almost all the solutions I found but nothing is working.
services.yml
# Configure Cross-Site HTTP requests (CORS).
# Read https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
# for more information about the topic in general.
# Note: By default the configuration is disabled.
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
allowedHeaders: ['x-csrf-token','authorization','content-type','accept','origin','x-requested-with', 'access-control-allow-origin','x-allowed-header','*']
# Specify allowed request methods, specify ['*'] to allow all possible ones.
allowedMethods: ['GET']
# Configure requests allowed from specific origins.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: false
# Sets the Access-Control-Max-Age header.
maxAge: false
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: true
I am using this xhr to fetch the data.
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://***.pantheonsite.io/page/performance/', true);
xhr.withCredentials = true;
xhr.setRequestHeader('Authorization', 'Basic ' + btoa("test:123456!"));
xhr.setRequestHeader('Content-Type', 'text/html');
xhr.onload = function () {
if (xhr.status === 200) {
console.log(xhr.responseText);
} else {
console.error(xhr.statusText);
}
};
xhr.send();
Any help would be appreciated!
I tested this on my test site where I enabled CORS like this:
cors.config:
enabled: true
# Specify allowed headers, like 'x-allowed-header'.
allowedHeaders: ['x-csrf-token','authorization','content-type','accept','origin','x-requested-with', 'access-control-allow-origin','x-allowed-header','*']
# Specify allowed request methods, specify ['*'] to allow all possible ones.
allowedMethods: ['*']
# Configure requests allowed from specific origins. Do not include trailing
# slashes with URLs.
allowedOrigins: ['*']
# Sets the Access-Control-Expose-Headers header.
exposedHeaders: true
# Sets the Access-Control-Max-Age header.
maxAge: false
# Sets the Access-Control-Allow-Credentials header.
supportsCredentials: true
I also enabled basic auth from Pantheon dashboard. Then, I sent a request like this:
curl -I --location ‘https://<DOMAIN>/node/1?_format=json’ \
--header ‘Origin: https://example.com’ \
--header ‘Authorization: Basic <base64encoded>’
And got this as response:
HTTP/2 200
access-control-allow-origin: https://example.com
cache-control: max-age=3600, public
content-language: en
content-type: application/json
... lots more headers here
Which makes me think that it's working as expected.
If things are still not working for you, could you please provide some more info? (e.g. example request, example response)
Hope this helps!

Fix CORS error using WPGraphQL plugin as a backend and NextJS as frontend

I've been struggling with this error after migrating a site from Google Cloud in which I was using Nginx and now I changed the hosting to an Apache server.
The website is in 2 sections front-end (hosted on Vercel NextJS) and the backend which is a WordPress site used as an API with GraphQL (this is the one I migrated) I have used the GraphQL plugin and now the request from the front-end is getting this error:
Access to XMLHttpRequest at [backend domain] from origin [front end domain] has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I have added this to the .htaccess file:
Header add Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "GET,PUT,POST,DELETE"
Header set Access-Control-Allow-Headers "Content-Type"
I'm using Cloudflare in both the backend and the frontend.
Don't know what else to do. I have tried to go back to the previous hosting and it works perfectly so I don't know what's the problem! Please help! Thank you! :)
Add this filter in functions.php file in theme and make sure SSL enabled
add_filter('rest_pre_serve_request', 'cors_headersxxxx', 0, 4 );
function cors_headersxxxx() {
header( 'Access-Control-Allow-Origin: *');
header( 'Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE' );
header( 'Access-Control-Allow-Credentials: true' );
header( 'Access-Control-Allow-Headers: Authorization, Content-Type, X-Requested-With, X-Mystore-Cartkey, X-USER-ID' );
//header( 'Access-Control-Expose-Headers: X-Mystore-Cartkey' );
}
add_filter('rest_api_init', 'wp_mystore_jwt_add_cors_support');
function wp_mystore_jwt_add_cors_support() {
$enable_cors = true;
if ($enable_cors) {
$headers = 'Access-Control-Allow-Headers, X-Requested-With, Content-Type, Accept, Origin, Authorization';
header( sprintf( 'Access-Control-Allow-Headers: %s', $headers ) );
}
}
It's fixed! Apparently, I had to flush the permalinks by just saving the permalinks settings: Settings > Permalinks
I found the solution here: https://github.com/wp-graphql/wp-graphql/issues/213
This is not really safety but it works for me
I've put this to .htaccess file
Header set Access-Control-Allow-Origin '*'
Header set Access-Control-Allow-Headers '*'
Header set Access-Control-Allow-Methods '*'

CORS errors with Sabre API v2 calls

For the last few weeks, we started getting CORS errors when trying to retrieve the auth token v2 API. We installed chrome CORS plugin and got that to work for now but then the flight fares API started giving CORS errors, we tried providing the regular cors headers in the request but to no avail. here is what is seen in the developer console. I am sending a GET request for the flight fares and tried the regular CORS headers as well but to no avail..
var getFlightFares = {
method: 'GET',
url: mainURL + "/v2/shop/flights/fares",
headers: {
'Authorization': 'Bearer '+token,
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': "/"
//'Access-Control-Allow-Origin': '*',
//'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
//'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
}
};
Result in developer console
GET
http://127.0.0.1:8080/spa/images/flights/sm%7B%7Bcheckout1.returnAirlineCode%7D%7D.gif [HTTP/1.1 200 OK 0ms]
OPTIONS
XHR
https://api.test.sabre.com/v2/auth/token [HTTP/1.1 200 OK 623ms]
POST
XHR
https://api.test.sabre.com/v2/auth/token [HTTP/1.1 200 OK 152ms]
Response :
Object { data: Object, status: 200, headers: dd/<(), config: Object, statusText: "OK" } sabre_integration.js:311:5
tokenT1RLAQJyP+PPcbBSEiIy9JBZrGkt4nu/dBD6CkzcyWI0njOM/Bbn3ngcAADA961ZaE1tN5y/bu57k0DseB5ocYDY9AIj64EwVJOr4RYAHKZF+H8tL7QnM35wjKYr40yjxkp1XL8lRDx84B+whxOMTaDreGnp1tDtFPhCGilvfeFpuXawbf1PjWAsR0uoNE9c0Pnmk8qWwuYEgNEkODYs8+K/peXF97LqylCFC6MWmkyodwSGwH7D/hjD5wTcSqJGLvARwo2NY/hplnArn8rY3sZ9gN3JV5PhqyPks56PYyD0Y5WvABg8YOVEA/Ud sabre_integration.js:312:5
OPTIONS
XHR
https://api.test.sabre.com/v2/shop/flights/fares [HTTP/1.1 404 Not Found 100ms]
Headers
Params
Response
departuredate2016-12-06destinationLAXlengthofstay5originJFKpointofsalecountryUS
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://api.test.sabre.com/v2/shop/flights/fares?origin=JFK&destination=LAX&departuredate=2016-12-06&lengthofstay=5&pointofsalecountry=US. (Reason: CORS preflight channel did not succeed). (unknown)
GET
http://127.0.0.1:8080/spa/images/flight_listing_sprite.png [HTTP/1.1 200 OK 33ms]
Try opening google chrome from command prompt with the commands:
"chrome.exe --disable-web-security --user-data-dir=/path/to/foo"
check there then

Error doing a post from a dart app to a laravel 4 api using CORS

I have a REST API developed using Laravel 4. The client is written using Dart Language.
When my Dart app does a GET it all works fine, but when it does a post I get this error:
XMLHttpRequest cannot load http://localhost:8000/api/v1/users. Origin http://127.0.0.1:3030 is not allowed by Access-Control-Allow-Origin.
My Dart function making the request:
void submitForm(Event e) {
e.preventDefault(); // Don't do the default submit.
request = new HttpRequest();
request.onReadyStateChange.listen(onData);
// Get Basic Auth credentials
var auth_string = 'admin:admin'; // Default admin login for creating new user accounts
var auth_base64 = window.btoa(auth_string);
var authorization = 'Basic '+auth_base64;
// POST the data to the server.
var url = 'http://localhost:8000/api/v1/users';
request.open('POST', url);
request.withCredentials = true;
request.setRequestHeader('Authorization',authorization);
request.setRequestHeader('Content-Type','application/json');
print(siftedregistrationAsJsonData());
request.send(siftedregistrationAsJsonData());
}
My Laravel 4 before and after filter (as defined in filters.php):
App::before(function($request)
{
if($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
$statusCode = 204;
$headers = [
'Access-Control-Allow-Origin' => 'http://localhost:3030',
'Access-Control-Allow-Methods' => 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers' => 'Origin, Content-Type, Accept, Authorization, X-Requested-With',
'Access-Control-Allow-Credentials' => 'true',
'Access-Control-Max-Age' => '86400'
];
return Response::make(null, $statusCode, $headers);
}});
App::after(function($request, $response)
{
$response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3030');
$response->headers->set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
$response->headers->set('Access-Control-Allow-Headers', 'Origin, Content-Type, Accept, Authorization, X-Requested-With');
$response->headers->set('Access-Control-Allow-Credentials', 'true');
$response->headers->set('Access-Control-Max-Age','86400');
return $response;
});
And this is the header I get using Chrome Dev Tools:
Request URL:http://localhost:8000/api/v1/users
Request Method:OPTIONS
Status Code:204 No Content
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:origin, authorization, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:localhost:8000
Origin:http://127.0.0.1:3030
Referer:http://127.0.0.1:3030/Users/salarrahmanian/Dropbox/Projects/phpstorm/sifted/app/dart/web/out/sifted.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1530.0 (Dart) Safari/537.36
Response Headersview source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Origin, Content-Type, Accept, Authorization, X-Requested-With
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:http://localhost:3030
Access-Control-Max-Age:86400
Cache-Control:no-cache
Connection:close
Content-Type:text/html; charset=UTF-8
Date:Wed, 10 Jul 2013 18:38:42 GMT
Host:localhost:8000
X-Powered-By:PHP/5.4.14
Your help and input on this really appreciated.
Many thanks.
You're allowing origin http://localhost:3030, but then requesting from http://127.0.0.1:3030.
Change:
$response->headers->set('Access-Control-Allow-Origin', 'http://localhost:3030');
to
$response->headers->set('Access-Control-Allow-Origin', 'http://127.0.0.1:3030');
Note: Unfortunately you can't set Allow-Origin to '*' when using Authorization - Just an FYI in case you tried that also.

I can't make a DELETE with CORS and AngularJS

I'm trying to make a DELETE request with AngularJS.
I'm sending this headers from the Server:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: origin, x-requested-with, content-type, accept');
header('Access-Control-Allow-Method: GET, POST, OPTIONS, DELETE');
But in Chrome, when I do an
$http({method: 'DELETE', url: EmployeesURL + "remove/id/" + id})
it throws a Method DELETE is not allowed by Access-Control-Allow-Methods. error.
Looks like you are missing an 's' Access-Control-Allow-Methods

Resources