OJS 3.2.1.1
config.inc.php:
base_url = "https://maindomain.tld"
base_url[index] = https://maindomain.tld/index
base_url[abc] = https://customdomain.tld
base_url[def] = https://maindomain.tld/def
restful_urls = On
Apache configuration, maindomain.tld.conf:
RewriteEngine On
RewriteBase /
RewriteRule ^api/v1(.*)$ /index.php/api/v1$1 [L,R=307]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php/$1 [QSA,L]
Apache configuration, customdomain.tld.conf
Header unset Access-Control-Allow-Origin
Header unset Access-Control-Allow-Headers
Header unset Access-Control-Allow-Methods
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "Content-Type, X-Csrf-Token"
Header always set Access-Control-Allow-Methods "HEAD, POST, GET, OPTIONS, PUT, DELETE"
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_METHOD} !OPTIONS
RewriteRule ^api/v1(.*)$ /index.php/abc/api/v1$1 [L,R=307]
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [L,R=200]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /index.php/abc/$1 [QSA,L]
Steps:
- login as admin in maindomain.tld
- login as admin in customdomain.tld
- go to “Administration” in the left sidebar. This is always hosted from maindomain.tld
- go to “Hosted Journals”
- click on “Edit” for journal abc (which uses customdomain.tld)
- click “Save”
- This fires OPTIONS and PUT requests to customdomain.tld
- observe HTTP 403 with response body
{"error":"form.csrfInvalid","errorMessage":"The form could not be submitted. You may have been logged out. Please reload the page and try again."}
Note that all CORS-headers are correctly sent! There are no complaints about missing or duplicate Access-Control-Allow-Origin
headers or the like.
I dived into the OJS code and found this in lib/pkp/classes/security/authorization/internal/ApiCsrfMiddleware.inc.php
:
$session = Application::get()->getRequest()->getSession();
return $session && $session->getCSRFToken() === $server['HTTP_X_CSRF_TOKEN'];
And this seems to be the source of the 403. It turns out that the HTTP_X_CSRF_TOKEN which is sent from maindomain.tld is different from the $session->getCSRFToken()
which belongs to the login session of customdomain.tld.
This leads me to believe that using the Administration menu (which is always from maindomain.tld) will never work for journals which use a custom domain.
Does this look correct, or am I missing something?
Thanks in advance,
Jan Pieter