cancel
Showing results for 
Search instead for 
Did you mean: 

API: CORS requests will fail without OPTIONS reponse

0 Kudos

API: CORS requests will fail without OPTIONS reponse

Feature request from Silarn, posted on GitHub Feb 02, 2017

When trying to use JavaScript to make an API call where the methods follow JavaScript standards and make an OPTIONS request to the server to determine CORS compatibility, requests will always fail.

This is because Magento has no built-in method for handling OPTIONS requests and will return a 400 error in response.

Preconditions

  1. Magento 2.*
  2. An API call using Angular JS should do the trick

Steps to reproduce

  1. Have a running Magento install with a valid API account
  2. Obtain an authorization key to create an API request
  3. Make any request via AJAX in a standard browser (with valid authentication headers and request data)

Expected result

  1. The API receives an OPTIONS request for the API endpoint and provides valid CORS headers in response
  2. The AJAX call verifies the CORS headers and proceeds to make the API call

Actual result

  1. The API receives an OPTIONS request for the API endpoint and fails, returning a 400 response
  2. The AJAX call fails to validate CORS headers and stops

You can work around this by modifying the HTML server to return a valid response when any OPTIONS request is made, but this is less than ideal. Ideally each individual API endpoint can return valid CORS headers, and other pages will fail or disallow such requests.

7 Comments
New Member
Status changed to: Investigating
 
New Member

Comment from misha-kotov, posted on GitHub Feb 07, 2017

Thanks for your feedback. I've added CORS headers support as an improvement item for our APIs (MAGETWO-64314)

In the meantime, I understand that headers are extensible. Pasting the following from elsewhere, but to be honest I'm not entirely sure if it'll help in this case or not:

app/code/Magento/Store/etc/di.xml:337 \Magento\Framework\App\Response\HeaderManager Magento\Framework\App\Response\HeaderProvider\XssProtection

The idea is you inject a new "header provider" into the $headerProviderList parameter of Magento\Framework\App\Response\HeaderManager, and this header provider implements the interface \Magento\Framework\App\Response\HeaderProvider\HeaderProviderInterface, so it supplies the name and value of header and whether or not to add it.

New Member

Comment from Silarn, posted on GitHub Feb 08, 2017

Thanks for the tip. I've created a workaround in the Apache configuration for now, but this might be a better solution.

Regular Visitor

Per GitHub, here's my Apache workaround to allow CORS requests.

 

<VirtualHost *:80> # Or whatever VHost you're using
  # Your other rules
  RewriteEngine on
  RewriteCond %{REQUEST_METHOD} OPTIONS
  RewriteRule ^(.*)$ "index.html" [R=200,E=API:1,PT]
# This rewrite rule forces any OPTIONS request to return as a valid response.
# It sets the API environment variable for use below.
#
# You can try to put a placeholder file here for the response (index.html)
# Otherwise it'll look like an error page, but it'll return with a 200 response code.
# Since this is intended to pass along the headers below and likely wont be visible,
# it doesn't really matter what the response content is. <IfModule mod_headers.c> SetEnvIf Accept application/json API Header always set Access-Control-Allow-Origin "*" env=API Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT" env=API Header always set Access-Control-Allow-Headers "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization" env=API </IfModule> </VirtualHost>

 

Occasional Contributor

It's possible to do a workaround also in nginx configuration?, If Yes can you show how to do it?

Member

I have attempted to create an extension that allows CORS cross-domain requests without modifying your Apache and Nginx server configs. It handles the OPTIONS pre-flight request, and allows configuring the Origin domain in the Admin Configuration. Feel free to check it out, and let me know if I have implemented any part of the CORS protocol incorrectly (or if I have bugs in my Magento code!). Thanks

 

https://github.com/splashlab/magento-2-cors-requests

Regular Visitor

That looks like a great solution until/if/when they get around to implementing CORS in core, thanks!

 

I haven't pored over the module yet, but I plan to pull it and start testing soon.

 

@dandreoli The readme for that module includes an Nginix solution, if you happen to still be looking!