Greetings,
I'm having a weird problem using my under-construction Ruby API library to talk to Wikimedia wikis. Login to eg. en.wikipedia.org seems to work fine:
REQ: {"format"=>"xml", "lgpassword"=>"XXX", "action"=>"login", "lgdomain"=>"local", "lgname"=>"Jpatokal"} RES: <api><login result='NeedToken' cookieprefix='enwiki' token='b07fdd1582a3faeed6244b58577a2b19' sessionid='e310ae7389c8364e7ff4ac2e91258e54'/></api> REQ: {"format"=>"xml", "lgpassword"=>"XXX", "action"=>"login", "lgdomain"=>"local", "lgtoken"=>"b07fdd1582a3faeed6244b58577a2b19", "lgname"=>"Jpatokal"} RES: <api><login result='Success' lguserid='8155' cookieprefix='enwiki' lgusername='Jpatokal' sessionid='e310ae7389c8364e7ff4ac2e91258e54' lgtoken='3006f107e16173abcc8d9a2d46fbfea4'/></api>
I can request an edit token for a page and get back a seemingly suitable one:
REQ: {"intoken"=>"edit", "format"=>"xml", "action"=>"query", "titles"=>"User:Jpatokal/Sandbox", "prop"=>"info"} RES: <api><query><pages><page starttimestamp='2010-08-11T10:26:00Z' pageid='26692065' touched='2010-04-23T04:55:02Z' lastrevid='357765946' title='User:Jpatokal/Sandbox' edittoken='6069665f65933586ddfa540d38d30d6a+\' ns='2' counter='0' length='67'/></pages></query></api>
However, when I send it back, it's rejected with "badtoken".
REQ: {"format"=>"xml", "title"=>"User:Jpatokal/Sandbox", "token"=>"6069665f65933586ddfa540d38d30d6a+\", "text"=>"haxx0r", "action"=>"edit", "summary"=>""} RES: <api><error code='badtoken' info='Invalid token'/></api>
What's wrong? The same sequence works fine on my local test wiki. Here's a packet trace of the actual edit request, which looks fine to me, including the URL-encoding of the token:
POST /w/api.php HTTP/1.1 Accept: */*; q=0.5, application/xml User-Agent: MediaWiki::Gateway/0.0.1 Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate Cookie: centralauth_Session=f5b0c979d3097489deca4b759f9d49af;centralauth_Token=8f57e36225df5a8f71cfd623718dff59;centralauth_User=Jpatokal;domain=.wikipedia.org;enwikiUserID=8155;enwikiUserName=Jpatokal Content-Length: 120 Host: en.wikipedia.org
format=xml&title=User%3AJpatokal%2FSandbox&token=6069665f65933586ddfa540d38d30d6a%2B%5C&text=haxx0r&action=edit&summary=
Cheers, -jani
2010/8/11 Jani Patokallio jpatokal@iki.fi:
Greetings, Cookie: centralauth_Session=f5b0c979d3097489deca4b759f9d49af;centralauth_Token=8f57e36225df5a8f71cfd623718dff59;centralauth_User=Jpatokal;domain=.wikipedia.org;enwikiUserID=8155;enwikiUserName=Jpatokal
Are you sure this is complete? I see no session or token cookies for enwiki.
What happens when you rerequest the token afterwards? Do you get the same token or a different one?
Roan Kattouw (Catrope)
Are you sure this is complete? I see no session or token cookies for
enwiki.
A-ha! Thanks, that was the key -- enwiki_session is sent only in the initial response, so you need to merge, not overwrite, that with the Set-Cookie from the second response. Here's the minimum set required:
{"centralauth_User"=>"Jpatokal", "enwikiUserID"=>"8155", "domain"=>".wikipedia.org", "centralauth_Token"=>"8f57e36225df5a8f71cfd623718dff59", "enwiki_session"=>"356044244f4316fbaadc42077ddecf4f", "enwikiUserName"=>"Jpatokal", "centralauth_Session"=>"32cc0e3f5d27c0135c4b8739b8d9e172"}
In Ruby:
def make_api_request(form_data) RestClient.post(@wiki_url, form_data, @headers.merge({:cookies => @cookies})) do |response, &block| ... @cookies.merge!(response.cookies) end end
Cheers, -j.
mediawiki-api@lists.wikimedia.org