Eduardo Garcia bio photo

enzo

Eduardo Garcia

Knowmad by definition

Location: Costa Rica

Twitter Facebook  QQ交谈 Google+ Github LinkedIn Feed

The Problem

Nowadays I was creating a new version of my library https://github.com/enzolutions/backbone.drupal to enable to use Drupal 8 in mode Headless Drupal using front end in a different domain or subdomain.

The problem I found with CORS requests is related with the way jQuery execute the first request Ajax, because before to do an execution of a GET|PUT|DELETE|POST|PATCH request an OPTIONS request is executed to validate request methods accepted for backend server more information at http://api.jquery.com/jquery.ajax/ in contentType section.

The current status of Rest module (part of Drupal Core) doesn't implement the OPTIONS method, so my first approach was implement that method in class Drupal\rest\Plugin\rest\resource\EntityResource using the following code

public function options(EntityInterface $entity) {
   $response = new ResourceResponse();
   $response->setStatusCode(ResourceResponse::HTTP_OK);
   $response->headers->set('Allow', 'GET,POST,PATCH,DELETE,OPTIONS');
   return $response->send();
  }

After add that extra function in class EntityResource the method was available and double checked with module RestUI, but this solution wasn't enough because I can't enable OPTIONS method without authentication and jQuery trigger the OPTIONS method without CRC Token or Basic Auth method even if you provide in the original call.

The Solution

In order to resolve the problem I use .htaccess and Apache mod_rewrite to enable CORS and intercept the OPTIONS request to avoid Drupal reject the request because doesn't have the proper credentials, I did a patch for Drupal 8 and you can download the patch here.

But let me explain the changes introduced in my patch.

Intercept OPTIONS Request

I add a Mod Rewrite Condition and Rule to avoid all OPTIONS request be processed by Drupal and rejected, instead of a HTTP 200 OK code is returned in order to enable jQuery request continue with the normal workflow.

Check the code below.

RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]

Enable CORS

If you search how to enable CORS using .htaccess you will find tons of similar information and this information usually works, but in our case we have a special situation the intercept process we implemented above.

Because the interception the normal statements to enable CORS doesn't work and apache will reject our request, to resolve this problem I found the condition always for Header directive.

Check the implementation below.

Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PATCH, DELETE"
Header always set Access-Control-Allow-Headers: Authorization

I strongly recommend to change * for your frontend domain i.e frontend-example.com.

I expect you have found this entry useful.


Comments

comments powered by Disqus