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

Cross-Origin request blocked using multi-user setup #81

Open
jmformenti opened this issue Apr 22, 2023 · 8 comments
Open

Cross-Origin request blocked using multi-user setup #81

jmformenti opened this issue Apr 22, 2023 · 8 comments
Labels

Comments

@jmformenti
Copy link

We are working on a VUE application (client side rendering) to manage our own Wikibase instance and we want users to login using our application with OAuth.

We have our OAuth authentication process against Wikibase implemented and got access tokens properly but when we try to execute our first action with wikibase-edit:

this.wbEdit.label.set({ id: 'Q35702', language: 'ca', value: 'Universitat de Salamanca' }, requestConfig)

we got this error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/w/api.php?action=query&meta=tokens&type=csrf&format=json. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost/w/api.php?action=query&meta=tokens&type=csrf&format=json. (Reason: CORS request did not succeed). Status code: (null).

We are following this documentation: https://github.com/maxlath/wikibase-edit/blob/main/docs/how_to.md#multi-user-setup

What are we doing wrong? Can wikibase-edit be used from javascript running in the browser?

@maxlath
Copy link
Owner

maxlath commented Apr 22, 2023

Hi @jmformenti, it should be possible to use wikibase-edit in the browser since #47, but I don't use that possibility and we don't have tests to assert that unfortunately. Maybe @SirkoS knows more about the topic?

Reading mediawiki docs on CORS, it seems we might be missing the possibility to pass an origin parameter in the post request querystring. That origin parameter would need to match an origin set in $wgCrossSiteAJAXdomains in your mediawiki.

Could you try to set that $wgCrossSiteAJAXdomains, and then change your local version of wikibase-edit to hard-code query.origin = 'https://your.wikibase.instance' in lib/request/post.js actionPost function, and see if that works?

@jmformenti
Copy link
Author

Thanks @maxlath, I've realized that the failing request is this one:
https://github.com/maxlath/wikibase-edit/blob/main/lib/request/get_final_token.js#L10

I've added origin=* and I've already set $wgCrossSiteAJAXdomains = [ '*' ]; in my Wikibase but I'm getting the same error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://wikibase.svc/w/api.php?action=query&meta=tokens&type=csrf&format=json&origin=*. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 200.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://wikibase.svc/w/api.php?action=query&meta=tokens&type=csrf&format=json&origin=*. (Reason: CORS request did not succeed). Status code: (null).

My guess is that this is a special request precisely to get CSRF tokens and maybe origin parameter is ignored

@AlexW00
Copy link

AlexW00 commented Jun 7, 2023

The issue is that wb-edit does not add the origin parameter when making requests to the Wikibase API. In a node.js environment this does not matter, but in the browser, the CORS header in the response must match (security).
origin=* in $wgCrossSiteAJAXdomains does not work because credentials must not be sent over a wildcard origin (https://stackoverflow.com/questions/19743396/cors-cannot-use-wildcard-in-access-control-allow-origin-when-credentials-flag-i). Therefore, for each request, there has to be an url parameter origin present, that matches one of the allowed origins configured in $wgCrossSiteAJAXdomains. I patched this by adding an origin to each request in fetch.js (https://github.com/AlexW00/wikibase-edit/blob/a0f456a9a1cd0aa2ba34e248bbfc52f1321b2bea/lib/request/fetch.js#L30) like so:

const addOrigin = (url, origin) => {
  const urlObj = new URL(url)
  urlObj.searchParams.set('origin', origin)
  return urlObj.toString()
}

There is also another issue when trying to make wb-edit work in the browser: cookie management. In the browser, it is not possible to manage cross-site cookies (security). I replaced cross-fetch with axios to use a cookie jar, which essentially handles all the cookies automatically. I'm sure there are better solutions, but for now, it works.

I created a fork, which runs fine in the browser now. However, I haven't tested it with Node.js yet. Furthermore, for node.js, the origin header is hard-coded (laziness) in fetch.js. For the browser, the origin is automatically pulled from window.location.origin.

Fork: https://github.com/AlexW00/wikibase-edit
Npm (dev package for easy installation): https://www.npmjs.com/package/wikibase-edit-browser

@jmformenti
Copy link
Author

Thanks a lot @AlexW00, I'm trying to use your fork but I'm getting the same error, not sure if I'm doing something wrong.
This is the code that I'm testing:

    this.wbEditBrowser = require('wikibase-edit-browser')({
      instance: 'http://localhost',
      credentials: {
        username: 'admin',
        password: 'XXX'
      }
    })
    this.wbEditBrowser.label.set({ id: 'Q35702', language: 'ca', value: 'test' })

In order to make it work in my case (a VUE application with client side rendering) I needed to change this line: https://github.com/AlexW00/wikibase-edit/blob/main/lib/request/client.js#L1 for: const axios = require('axios').default.
But after that, I'm getting the same error than before:
Captura de pantalla de 2023-06-09 20-43-56
Any idea?

@AlexW00
Copy link

AlexW00 commented Jun 10, 2023

Thanks a lot @AlexW00, I'm trying to use your fork but I'm getting the same error, not sure if I'm doing something wrong. This is the code that I'm testing:

    this.wbEditBrowser = require('wikibase-edit-browser')({
      instance: 'http://localhost',
      credentials: {
        username: 'admin',
        password: 'XXX'
      }
    })
    this.wbEditBrowser.label.set({ id: 'Q35702', language: 'ca', value: 'test' })

In order to make it work in my case (a VUE application with client side rendering) I needed to change this line: https://github.com/AlexW00/wikibase-edit/blob/main/lib/request/client.js#L1 for: const axios = require('axios').default. But after that, I'm getting the same error than before: Captura de pantalla de 2023-06-09 20-43-56 Any idea?

What does console.log(window.location.origin) print out? Is this value in your $wgCrossSiteAJAXdomains?

@jmformenti
Copy link
Author

What does console.log(window.location.origin) print out? Is this value in your $wgCrossSiteAJAXdomains?

I've double-checked it, the window.location.origin=http://localhost:3000 and the final request is:

http://localhost/w/api.php?action=login&format=json&origin=http://localhost:3000

And this is my config in Wikibase:

$wgCrossSiteAJAXdomains = [ 'http://localhost:3000' ];

My Wikibase version is 1.36.4.

@AlexW00
Copy link

AlexW00 commented Jun 12, 2023

What does console.log(window.location.origin) print out? Is this value in your $wgCrossSiteAJAXdomains?

I've double-checked it, the window.location.origin=http://localhost:3000 and the final request is:

http://localhost/w/api.php?action=login&format=json&origin=http://localhost:3000

And this is my config in Wikibase:

$wgCrossSiteAJAXdomains = [ 'http://localhost:3000' ];

My Wikibase version is 1.36.4.

In your wbEditConfig object, the port of your wikibase instance seems to be missing. On which port is wikibase running? If it is 8181 can you try it with the following config object? Btw I also published an update to the fork, which fixed another bug. I recommend you update wikibase-edit-browser first.

    this.wbEditBrowser = require('wikibase-edit-browser')({
      instance: 'http://localhost:8181',
      credentials: {
        username: 'admin',
        password: 'XXX'
      }
    })
    this.wbEditBrowser.label.set({ id: 'Q35702', language: 'ca', value: 'test' })

@jmformenti
Copy link
Author

In your wbEditConfig object, the port of your wikibase instance seems to be missing. On which port is wikibase running? If it is 8181 can you try it with the following config object? Btw I also published an update to the fork, which fixed another bug. I recommend you update wikibase-edit-browser first.

It is running on port 80, I'll try to upgrade Wikibase to discard some problem with that version

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

No branches or pull requests

3 participants