Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In subdomain-per-language scenarios, babel_view does not work because of CORS #310

Open
Rudd-O opened this issue Mar 27, 2018 · 5 comments

Comments

@Rudd-O
Copy link

Rudd-O commented Mar 27, 2018

My site runs with a VHM translation like this:

      if (req.http.host == "es.rudd-o.com")
      {
          set req.url = regsub(req.url,"^", "/VirtualHostBase/" + req.http.Protocol + "/" + req.http.host + "/Rudd-O.com/es/VirtualHostRoot");
      }
      else
      {
          set req.url = regsub(req.url,"^", "/VirtualHostBase/" + req.http.Protocol + "/" + req.http.host + "/Rudd-O.com/en/VirtualHostRoot");
      }

So that rudd-o.com runs the /en folder, and es.rudd-o.com runs the /es folder.

When I go to the Babel edit page of any translated content, the URL .../content-item-id/babel_view is loaded via XHR to display the original content on the left side of the Babel editor.

But here's the catch: since the item I am editing is in /en and loads via rudd-o.com, but the original item is in /es and loads via es.rudd-o.com (automatic redirect to prevent duplicate content in search engines), the browser does a CORS preflight request (an OPTIONS request) prior to loading it.

I've already set the correct CORS headers for the OPTIONS request:

< allow: GET, POST, OPTIONS
< access-control-allow-origin: https://rudd-o.com
< access-control-allow-credentials: true
< access-control-allow-methods: GET, POST, OPTIONS
< access-control-allow-headers: x-crsf-token,x-requested-with,cookie,authorization

but then the subsequent GET request, which should include the Cookie: or the Authorization: header (both valid for the entire domain, not just the host name), does not include the credentials.

What this has as net effect is that the babel_view becomes a 302 Found redirect to the Plone login page. And, of course, the original text does not load.

Now, I've verified correctly that the babel_view XHR loads correctly, when the credentials are specified with cURL as headers. So it's not a problem with the URL rewriting. I've also verified that the browser does not send the Cookie: or Authorization: header, which is what is causing the 302 Found redirect.

I believe the correct solution is to use the withCredentials: true parameter to whatever JavaScript XHR code is loading the babel_view page in the babel_edit view. That way, the browser will honor the Access-Control-Allow-Credentials: true CORS directive, and the Plone site will serve the original language content to the Babel editor.

Thanks for fixing this!

@erral
Copy link
Member

erral commented Mar 27, 2018

I would say that you should not edit the site like this. In the end you are relying on Zope Acquisition to edit the site: you can always get /en inside /es. I would say this is a "hack".

In this case of scenarios (edit the content of one site served through several domains), we configure a special admin domain (admin.rudd-o.com) pointing to the root of the Plone site to edit the contents.

@Rudd-O
Copy link
Author

Rudd-O commented Mar 27, 2018

This is where it craps out:

langSource = $('#frame-content #view_language')[0].innerHTML;

XHR requests to authenticated data need to specify withCredentials: true. Not doing it is a bug, and that it happens to work in the single-domain case is grandfathered happenstance, not specified behavior.

Ideally, the code that wires babel_view into the acquisition tree would also go further and detect preflight OPTIONS requests, then issue the appropriate Access-Control-Allow-Origin header using a custom view for the OPTIONS case. For now, I'm using my Varnish frontend to patch around that problem.

Just because there are bugs in the code does not mean the right solution is to work around them by actual hacks, like setting up an admin domain just because CORS is broken by the code. There is no reason why I should be forced to use an admin domain when what's buggy is the manner in which the XHR request is being done. plone.app.multilingual advertises support for multi-subdomains per-language domains — it is logical that a bug which prevents this feature from working should be fixed.

FYI, the site does have an admin domain, but that requires a special HTTP Authorization header, and it's not the same as my regular editor login, so that hack is a no-go.

@erral
Copy link
Member

erral commented Mar 28, 2018

I don't think this has ever been a feature of plone.app.multilingual.

In fact there is one setting in the multilingual settings of Plone (in Plone 4.3 PloneLanguageTool and Plone 5 in ILanguageUtility) regarding the use of subdomains.

And what this setting does is to decide the language for the user according to the subdomain setting. I don't know if it works, because I haven't ever used it.

That's why I say that I don't think that your use case is in any case supported.

@Rudd-O
Copy link
Author

Rudd-O commented Mar 28, 2018

I've been using that multi-domain feature for close to a decade (since LinguaPlone, yes) and it works, but -- as you can see from this bug report -- the editor does not work very well in p.a.m because of implementation decisions unique to p.a.m. Furthermore, multi-domain is practically the only way one can get a search engine to index multilingual sites.

I'm surprised you don't even know this feature works and has existed for a decade. I'm guessing more testing would have allowed the devs to figure out this broke before p.a.m. superseded LinguaPlone.

@erral
Copy link
Member

erral commented Mar 28, 2018 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants