Hi there,
On a running project we’re using Wordpress as a headless CMS using only the WP Rest API to get data in a React frontend using Next.js. For the frontend we’re using Docker Compose with Gitlab CI for deployment and for the backend Trellis.
The frontend & backend are available on 3 environments, on (as example) these domains:
http://mydomain.test => http://admin.mydomain.test
https://staging.mydomain.io => http://admin.staging.mydomain.io
https://mydomain.io => http://admin.mydomain.io
Each Trellis server should only be allowed to return the WP Rest API get requests from the matching environment, so I added a variable name in every group_vars environment called front_url
:
wordpress_sites:
admin.mydomain.io:
site_hosts:
- canonical: admin.mydomain.test
redirects:
- www.admin.mydomain.test
local_path: ../site
multisite:
enabled: false
ssl:
enabled: false
provider: self-signed
cache:
enabled: false
env:
front_url: http://mydomain.test
front_domain: mydomain.test
In my headless WP theme, I set the CORS header based upon this env var:
function get_frontend_origin() {
return FRONT_URL;
}
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: ' . get_frontend_origin());
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Credentials: true');
return $value;
});
}, 15);
Which works great!
Now my problem started when I needed an extra subdomain on my frontend that should also be able to use my WP Rest API:
http://mydomain.test,
http://sub.mydomain.test => http://admin.mydomain.test
https://sub.staging.mydomain.io,
https://staging.mydomain.io => http://admin.staging.mydomain.io
https://sub.mydomain.io,
https://mydomain.io => http://admin.mydomain.io
Since it’s not possible to use wildcards in the Access-Control-Allow-Origin header, I tried to use the
$_SERVER['HTTP_ORIGIN']
value and check that against an array of allowed domains, but for some reason the $_SERVER['HTTP_ORIGIN']
value is always empty?
So then I thought, I will remove these CORS settings in PHP and will try to add it in a nginx-includes template in Trellis and bumped into this example to set the headers based upon the $http_origin
.
So I added this structure in the root of my trellis folder:
trellis
└──nginx-includes/
└── admin.mydomain.io/
└── cors.conf.j2
With the following rules in cors.conf.j2:
location ~ ^/wp-json/ {
set $cors "";
if ($http_origin ~* (.*\.{{ site.env.front_domain }})) {
set $cors "true";
}
if ($cors = "true") {
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET';
add_header 'Access-Control-Allow-Headers' 'User-Agent,Keep-Alive,Content-Type';
}
}
But a re-provision results in an error:
AnsibleUndefinedVariable: 'site' is undefined
So my main question is, how can I use my front_domain
variable from group_vars in my nginx-includes Jinja2 template like this?
Since the template is already in it’s separate site folder, how can I access it’s group_vars?
Any help is welcome, thanks!