NGINX Wordpress REST API not working with allow/deny in location block
as you requested, I'm posting my comments as an answer:
Instead of using regex (which could be a little slower) you could use a simple location. Also, since the logic to redirect the "pretty" permalinks to the correct PHP file is inside another location directive, you need to copy it to your new custom location:
location /wp-json/ {
allow x.x.x.x;
deny all;
try_files $uri $uri/ /index.php?$args;
}
NOTE: you might need to adjust the actual try_files
location
manifestor
Updated on September 18, 2022Comments
-
manifestor almost 2 years
I'm trying to restrict access to a WordPress REST API with NGINX (it's the main backend
server {}
block, no proxy):location ~ ^/wp-json/ { allow x.x.x.x; deny all; }
The problem is, that WordPress always returns a
404
when trying to access an API endpoint (www.example.com/wp-json/wp/v2/pages
e.g.) with that configuration (no matter if it is the browser, which is passing all Cookies and Authorization stuff, orcURL
):curl -X GET -Ik https://www.example.com/wp-json/wp/v2/taxonomies HTTP/2 404 date: Thu, 17 Jan 2019 12:40:12 GMT content-type: application/json; charset=UTF-8 x-robots-tag: noindex x-content-type-options: nosniff access-control-expose-headers: X-WP-Total, X-WP-TotalPages access-control-allow-headers: Authorization, Content-Type
But once I comment out the
location
block, I get no errors when I access the site with a browser.I'm afraid that happens because I need to pass some HTTP headers for authorization purposes, as I have these HTTP headers in my REQUEST (checked with chrome devtools):
:authority: www.example.com :method: GET :path: /wp-json/wp/v2/taxonomies?context=edit&lang=en&_locale=user :scheme: https accept: application/json, */*;q=0.1 accept-encoding: gzip, deflate, br accept-language: en-US,en;q=0.9 (!) ---> authorization: Basic crf344...fdfs334 cache-control: no-cache (!) ---> cookie: wordpress_test_cookie=WP+Cookie+check; wordpress_logged_in_282...7da; wp-settings-1=mfo...off; wp-settings-time-1=1547726728 pragma: no-cache referer: https://www.example.com/wp-admin/post.php?post=193&action=edit (!) ---> x-wp-nonce: df238g3ds2
Could someone help me please in order to configure the
location
block properly for the WordPress REST API?EDIT:
I managed to get a
200
withcURL
if I add the corresponding HTTP headers:curl -X GET -H "authorization: Basic c2F...TVY" \ -H "cookie: wordpress_test_cookie=WP+...7da; \ wp-settings-1=mfo...off; \ wp-settings-time-1=1547726728" -H "x-wp-nonce: df238g3ds2" \ -H "referer: https://www.example.com/wp-admin/post.php?post=193&action=edit" \ -I https://www.example.com/wp-json/wp/v2/pages
How could I do the same with the NGINX
location
block?-
NuTTyX over 5 yearsWhy do you use
location ~ ^/wp-json/ {
instead of simplylocation /wp-json/ {
? No need to perform regex with that string (it is slower). Also, have you double checked in logs that the IP you are allowing is the same as the one you are using to reach the site? -
manifestor over 5 years@NuTTyX yes I checked the IP. Even if I delete all
allow
anddeny
statements I get a404
, if the block is commented out, it works. Thanks for your hint regarding the regex :) -
NuTTyX over 5 yearsNow that I think of it, you must have some directive to translate the short and readable uri into the proper php file in the wordpress. Check in other locations for parameters like
try_files
and try to replicate them inside your new location directive. -
manifestor over 5 years@NuTTyX yes, thank you! I missed a
try_files $uri $uri/ /index.php?$args;
. Post it as an answer, I want to give you some points! :)
-