我正在尝试API:Login文档中描述的Wikipedia客户端登录流程,但发生了一些错误:
1) 我正确地获得了一个使用 HTTP GET 提出的令牌https://en.wikipedia.org/w/api.php?action=query&meta=tokens&type=login&format=json
我得到一个有效的logintoken字符串。
2.1)然后我尝试clientlogin类似:
HTTP POST/w/api.php?action=clientlogin&format=json&lgname=xxxx&lgtoken=xxxx%2B%5C
POST BODY 是
{
"lgpassword" : "xxxxx",
"lgtoken" : "xxxxx"
}
但我收到一个错误:
{
"error": {
"code": "notoken",
"info": "The \"token\" parameter must be set."
},
"servedby": "mw1228"
}
如果我尝试更改lgtoken为,token我会得到相同的结果。
2.2)然后我尝试了旧方法action=login,即传递正文,但它不起作用,因为它给了我另一个登录令牌:HTTP POSThttps://en.wikipedia.org/w/api.php?action=login&format=json&lgname=xxxx
和相同的 POST BODY
然后我得到
{
"warnings": {}
},
"login": {
"result": "NeedToken",
"token": "xxxxx+\\"
}
这里的文档指出
NeedToken if the lgtoken parameter was not provided or no session was active (e.g. your cookie handling is broken).
但如图所示,我已经通过了lgtokenjson 正文。我正在使用Node.js和内置http模块,它应该以Cookies正确的方式传递和保持会话(使用其他 api 可以正常工作)。
我在这里的 LrMediaWiki 客户端上发现了类似的问题。
[更新] 这是我目前的实现:
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%s\n%@", error.message, error.stack);
return reject(error);
});
});
}//loginUser
哪里this.api是 Node.js http 的简单包装器,源代码可在此处获得,api 签名如下:
Promise:API.RequestGetP(url,headers,querystring)
Promise:API.RequestPostP(url,headers,querystring,body)