9

Drupal 8 has RESTful web service in-built in core and since 8.2 we don't need cors module.

Now to use services we just enable and configure default.service.yml file as specified in here

However, I was not able to configure this setup to allow web service access over another domain.

My current service.yml setup for cors is:

cors.config:
    enabled: true
    # Specify allowed headers, like 'x-allowed-header'.
    allowedHeaders: ['x-csrf-token,authorization,content-type,accept,origin,x-requested-with']
    # Specify allowed request methods, specify ['*'] to allow all possible ones.
    allowedMethods: ['POST, GET, OPTIONS, DELETE, PUT']
    # Configure requests allowed from specific origins.
    allowedOrigins: ['*']
    # Sets the Access-Control-Expose-Headers header.
    exposedHeaders: false
    # Sets the Access-Control-Max-Age header.
    maxAge: 1000
    # Sets the Access-Control-Allow-Credentials header.
    supportsCredentials: false

I googled to find further detailed configuration on this but could not find one.

I am creating this for test development across two different domains.

Using pantheon dev environment for web services and localhost custom .dev domain for consuming those services.

Service access working fine using chrome CORS extension.

  • If you have already changed your site/default/services.yml as it said in previous answers, and It didn't work, make sure that CORS is enabled in your web server. For example, in Nginx you have to add/modified a location in your server block configurantion see https://enable-cors.org/server_nginx.html – Pin Dec 27 '18 at 19:22
11

I ran into this fairly recently on Pantheon, and hopefully this helps if you haven't already solved it.

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.
    allowedOrigins: ['http://localhost/','http://localhost:3000','http://localhost:3001','http://localhost:3002','*']
    # 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

A few things to note...

Regarding the location of the file on Pantheon, please make sure your service.yml file is in /sites/default vs just /sites. I was wrongly under the impression it would work from both places. It will only work if in the /sites/default directory.

Notice the comma separated list of allowedHeaders each in their own set of quotes. I originally had a single string like you do in your example above, and it failed countless times before I caught the subtle difference. I'm fairly certain allowedMethods works the same way if you specifically want to list out your methods.

Please also note that while my code snippet will work well for development against a Pantheon sandbox you will likely want to lock things down a bit more prior to going into production. With Pantheon offering HTTPS you will also want to make sure to use it if you are going to be passing information around through headers. Hope this helps either you if you are still having issues or someone else that stumbled upon it down the road.

  • 3
    Why specify allowedOrigins and then also pass '*' ? – Christian Jun 20 '18 at 2:05
  • Simply to show both options. Please feel free to omit one or the other. – Shawn Matthews Jun 21 '18 at 15:02
  • exposedHeaders should be false or an array, per drupal.org/project/drupal/issues/2905848 – John Jul 12 at 14:50
  • If anyone's interested, I don't believe that the allowedOrigins field accepts regex. I tried a use a regex pattern to whitelist multiple sub-domains, and drupal complained. I had to use an explicit list of domains, comma-separated, like in this example. I was hoping it would behave like the trusted-hosts setting in settings.php – Tony Stecca Sep 9 at 14:51
8

Find: .../sites/default/default.services.yml

Make a copy and rename the copy to:

.../sites/default/services.yml

Find this part of the code: cors.config: enabled: false

and replace with the following - cors.config: enabled: true

Clear the cache.

  • I supposed tried everything till saw your answer, thanks for showing the most important point which is CLEARING THE CACHE (REBUILD CACHE) :D – emy Nov 14 at 14:22
4

The following setting working for me.

cors.config:
  enabled: true
  # Specify allowed headers, like 'x-allowed-header'.
  allowedHeaders: ['x-csrf-token','authorization','content-type','accept','origin','x-requested-with']
  # Specify allowed request methods, specify ['*'] to allow all possible ones.
  allowedMethods: ['*']
  # 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: false
0

exposedHeaders: true is not valid and will cause Warning: implode(): Invalid arguments passed in Asm89\Stack\CorsService->addActualRequestHeaders() (line 94 of /vendor/asm89/stack-cors/src/Asm89/Stack/CorsService.php) #0 /web/core/includes/bootstrap.inc(584) It needs to be either false or an array with allowed headers to expose see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.