I’m trying the Wikipedia client login flow depicted in the API:Login docs, but something wrong happens:
1) I correctly get a token raised with the HTTP GET https://en.wikipedia.org/w/api.php?action=query&meta=tokens&type=login&format=json
and I get a valid logintoken
string.
2.1) I then try the clientlogin
like:
HTTP POST /w/api.php?action=clientlogin&format=json&lgname=xxxx&lgtoken=xxxx%2B%5C
and the POST BODY was
{ "lgpassword" : "xxxxx", "lgtoken" : "xxxxx" }
But I get an error:
{ "error": { "code": "notoken", "info": "The "token" parameter must be set." }, "servedby": "mw1228" }
If I try to change lgtoken
to token
I get the same result.
2.2) I have then tried the old method i.e. action=login
and passing the body, but it does not work, since it gives me back another login token: HTTP POST https://en.wikipedia.org/w/api.php?action=login&format=json&lgname=xxxx
and the same POST BODY
I then get
{ "warnings": {} }, "login": { "result": "NeedToken", "token": "xxxxx+\"
}
where the docs here states that
NeedToken if the lgtoken parameter was not provided or no session was active (e.g. your cookie handling is broken).
but I have passed the lgtoken
in the json body as showed.
I’m using Node.js and the built-in http
module, that is supposed to pass and keep session Cookies
in the right way (with other api it works ok).
I have found a similar issue on a the LrMediaWiki client here.
[UPDATE] This is my current implementation:
Wikipedia.prototype.loginUser = function (username, password) { var self = this; return new Promise((resolve, reject) => { var cookies = self.cookies({}); var headers = { 'Cookie': cookies.join(';'), 'Accept': '*/*', 'User-Agent': self.browser.userAgent() }; // fetch login token self.api.RequestGetP('/w/api.php', headers, { action: 'query', meta: 'tokens', type: 'login', format: 'json' }) .then(response => { // success if (response.query && response.query.tokens && response.query.tokens['logintoken']) { self.login.logintoken = response.query.tokens['logintoken']; self.logger.info("Wikipedia.login token:%s", self.login); return self.api.RequestPostP('/w/api.php', headers, { action: 'login', format: 'json', lgname: username }, { lgpassword: password, lgtoken: self.login.logintoken }); } else { var error = new Error('no logintoken'); return reject(error); } }) .then(response => { // success return resolve(response); }) .catch(error => { // error self.logger.error("Wikipedia.login error%sn%@", error.message, error.stack); return reject(error); }); }); }//loginUser
where this.api
is a simple wrapper of the Node.js http, the source code is available here and the api signatures are like:
Promise:API.RequestGetP(url,headers,querystring) Promise:API.RequestPostP(url,headers,querystring,body)
Advertisement
Answer
I think from what you are saying you have lgtoken
and lgname
in the URL you are using, and then lgpassword
and lgtoken
(again!) in a JSON-encoded POST body.
This is not how the Mediawiki API works.
You submit it all as POST parameters. JSON is never involved, except when you ask for the result to come back in that format. I can’t help you fix your code as you don’t provide it, but that’s what you need to do. (If you edit your question with your code, I’ll do my best to help you.)
After seeing your code, I’ll presume (without knowing the detail of your code) that you want something like this:
return self.api.RequestPostP('/w/api.php', headers, { action: 'login', format: 'json', lgname: username, lgpassword: password, lgtoken: self.login.logintoken });